0

Currently I'm making my first video game using unity written in C#, but now I'm facing a trouble and I don't know what to do anymore. First I already made my character move but, I want to put all the attributes in one script, like it's moveSpeed, attackSpeed, etc. but once I access it to another script, my character just stands and do nothing. Here's my code

public class ClickToMove : MonoBehaviour {
    public CharacterController controller;          // Use to move the player
    private Vector3 position;                       // Store the position at which the player clicked;
    public Attributes attribute;

    // Animation variables
    public AnimationClip idleClip;
    public AnimationClip runClip;

    // Use this for initialization
    void Start () {
        position = transform.position;          // Set the position to player's current position
    }

    // Update is called once per frame
    void Update () {
        // Execute the code below once the player press left click
        if(Input.GetMouseButton(0)) {
            locatePosition();
        }
        moveToPosition();
    }

    // Locate at which the player clicked on the terrain
    private void locatePosition() {
        RaycastHit hit;                                                     // Get information from ray
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);        // A line in 3D space

        // Cast a ray that start from the camera with a distance of 1000
        if(Physics.Raycast(ray, out hit, 1000)) {
            // Store the position if the casted ray is not pointing to the player or enemy's position
            if(hit.collider.tag != "Player" && hit.collider.tag != "Enemy") {
                position = new Vector3(hit.point.x, hit.point.y, hit.point.z);
            }
        }
    }

    // Move to the located position
    private void moveToPosition() {
        // Check if the player position and the destination is greater than one
        if(Vector3.Distance(transform.position, position) > 1) {
            // Subtract the clicked position to the player position
            Quaternion newRotation = Quaternion.LookRotation (position - transform.position);
            // Disable the rotation from x and z angle
            newRotation.x = 0f;
            newRotation.z = 0f;
            // Rotate the player to a new rotation then move forward
            transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * attribute.moveSpeed);
            controller.SimpleMove(transform.forward * attribute.moveSpeed);
            animation.CrossFade(runClip.name);
        } else {
            animation.CrossFade(idleClip.name);
        }
    }
}

and here is the script I'm accessing

public class Attributes : MonoBehaviour {
    public float moveSpeed;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

I don't know what to do anymore. Any help will be appreciated. Thank you.

3
  • you never create an instance of Attributes, so the attributes member remains null Commented Nov 7, 2014 at 19:12
  • I do. i set the moveSpeed to 10 in unity Commented Nov 7, 2014 at 19:14
  • ah, I forgot about GUI assignments Commented Nov 7, 2014 at 19:18

1 Answer 1

1

There are a couple of things that you need to double check, the first being that you are actually assigning a value to attribute.moveSpeed in the inspector. Otherwise moveSpeed will always be 0 and therefore all of your multiplication operations will result in 0, resulting in no movement at all.

Second, make sure that something is actually being hit by your raycast. You can do this a couple ways, first by printing a message to the console saying that you hit something

// Cast a ray that start from the camera with a distance of 1000
if(Physics.Raycast(ray, out hit, 1000)) {

    // Send a debug message to Unity's console
    Debug.Log("I hit Something!");        

    // Store the position if the casted ray is not pointing to the player or enemy's position
    if(hit.collider.tag != "Player" && hit.collider.tag != "Enemy") {
        position = new Vector3(hit.point.x, hit.point.y, hit.point.z);
    }
}

and second by checking that the position variable changed values in the inspector. (Make the position variable public and look at your character's inspector)

Note that you've assigned a value to your attribute variable in the inspector because you're not getting NullReferenceExceptions

Sign up to request clarification or add additional context in comments.

3 Comments

How do we know they aren't getting a NullReferenceException? Just to be safe, the Start() function should include attribute = GetComponent<Attributes>()
@Agumander Because they would see thousands of red flags (one per frame) appear at the bottom of Unity's application, in the output tray. Unity makes it pretty clear that something wrong is happening, but not so bad as to stop your entire game. But yes, using attribute = GetComponent<Attributes>() would enforce it.
True, but a first-time user won't necessarily notice them. By default, the console is minimized and doesn't automatically show up when there's an error. The status bar would then only show one error, which might get missed if you don't know to look there. I've seen a few students have trouble with this; they often don't think to look for an error if the game is still running!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.