I’m messing around with my two scripts and an boolean variable.
Script A is a player script which wants to check if the variable “spearInAir” in script B (Spear Prefab) is true/false. But the Calling method “isSpearInAir” always returns false, althought the inspector and the debug line of script B says the bool is true. Here the code:
Script A (Player)
public Spear spearScript;
private void Update
{
if (Input.GetMouseButtonDown(1))
{
if (!spearInHand && !IsApearInAir())
{
CreateNewSpear();
spearInHand = true;
}
}
}
private bool IsApearInAir()
{
return spearScript.spearInAir;
}
Like I said, the Update Method of the spear is always returns me the correct status (false per default and true after “Throw” is called. But the Player Script (A) always returns false.
What am I missing? The connection in the inspector is set.
I’m guessing the answer is somewhere in the methods you didn’t show us. What is CreateNewSpear()? Where do you actually update the reference in spearScript? It would be to your advantage to show the whole code.
Hey @RadRedPanda thanks for your reply. Youre right, sorry. Guess is pretty hard to help if you can’t see everything.
Here are the full Scripts. I quite new so I guess I missing a complete essential point I cant find.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestPlayerControl : MonoBehaviour
{
[Header("Moving Variables")]
public bool isFacingRight = true;
public float movementSpeed = 10f;
public float walkAcceleration = 20f;
public float moveInput;
public float jumpingPower = 5f;
[Header("Throw Variables")]
public bool aiming = false;
public float throwPower = 1;
[Header("Linkings")]
[SerializeField] private Rigidbody2D rb;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
[SerializeField] public Transform hand;
[SerializeField] public Transform spear;
[SerializeField] public GameObject weapon;
public Spear spearScript;
public bool spearInHand;
private float holdDownTimeStart;
private float aimingTime;
private float throwForce;
// Vectoren für Handposition
Vector2 handAimPos;
Vector2 handIdlePos;
Vector2 handSwitch;
private void Start()
{
handSwitch = new Vector2(-0.5f, 0.4f);
spearInHand = false;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
holdDownTimeStart = Time.time;
handAimPosition();
}
if (Input.GetMouseButtonUp(0))
{
handIdlePosition();
if (spearInHand)
{
spearInHand = false;
}
}
moveInput = Input.GetAxisRaw("Horizontal");
if (Input.GetButtonDown("Jump") && IsGrounded())
{
rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 0f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
}
if (Input.GetMouseButtonDown(1))
{
Debug.Log("Player says:" + spearScript.spearInAir);
CreateNewSpear();
if (!spearInHand && !IsApearInAir())
{
CreateNewSpear();
spearInHand = true;
}
}
}
void FixedUpdate()
{
rb.velocity = new Vector2(moveInput * movementSpeed, rb.velocity.y);
}
/*private void Flip()
{
if (isFacingRight && moveInput < 0f || !isFacingRight && moveInput > 0f)
{
isFacingRight = !isFacingRight;
Vector2 localScale = transform.localScale;
localScale.x *= -1f;
transform.localScale = localScale;
}
}*/
private bool IsGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}
private void handAimPosition()
{
handIdlePos = hand.position;
handAimPos = handIdlePos + handSwitch;
hand.position = handAimPos;
}
private void handIdlePosition()
{
handAimPos = hand.position;
handIdlePos = handAimPos - handSwitch;
hand.position = handIdlePos;
}
public GameObject CreateNewSpear()
{
GameObject newSpear = Instantiate(weapon, hand.position, weapon.transform.rotation, gameObject.transform);
return newSpear;
}
private bool IsApearInAir()
{
return spearScript.spearInAir;
}
}
And…
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spear : MonoBehaviour
{
[Header("Linkings")]
public TestPlayerControl playerScript;
public Rigidbody2D rbSpear;
public BoxCollider2D colliderSpear;
[Header("Variables")]
public float launchForce;
public bool spearInAir;
Vector2 direction;
// Vectoren für Speerpositionen
Vector2 spearPosition;
Vector2 spearAimPos;
Vector2 handSwitch;
private void Start()
{
handSwitch = new Vector2(-0.5f, 0.4f);
}
void Awake()
{
rbSpear.isKinematic = true;
}
void Update()
{
Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
spearPosition = transform.position;
direction = mousePosition - spearPosition;
if (Input.GetMouseButtonDown(0))
{
spearAimPosition();
}
if (Input.GetMouseButton(0))
{
transform.right = direction;
}
if (Input.GetMouseButtonUp(0))
{
Throw();
}
}
private void FixedUpdate()
{
if (!playerScript.spearInHand)
{
float angle = Mathf.Atan2(rbSpear.velocity.x, rbSpear.velocity.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
}
public void Throw()
{
spearInAir = true;
rbSpear.bodyType = RigidbodyType2D.Dynamic;
rbSpear.gravityScale = 1;
rbSpear.AddForce(direction * launchForce, ForceMode2D.Impulse);
}
private void OnCollisionEnter2D(Collision2D collision)
{
GameObject.Destroy(this.gameObject);
}
private void spearAimPosition()
{
spearPosition = transform.position;
spearAimPos = spearPosition + handSwitch;
transform.position = spearAimPos;
}
}
Oh okay, but I referenced the prefab of Spear. So in my mind every newSpear instantiated will be referenced, cause the prefab is linked to the Player Script?
Do you have an idea how to easily fix this issue if im not right? Im quite confused now.
That’s not how it works, when you Instantiate a new spear, it’s going to be a different version of it. When you reference the spearScript in your code, it’s still trying to get the data from the prefab, which doesn’t exist in your game world. Instead, whenever you create a new spear, you need to point your spearScript variable to that one instead, it won’t do it automatically. All you really need to do is edit your CreateNewSpear method to do something like this.