我正在使用Unity3D创建一个演示。
演示是这样的:使用EasyTouch来控制名为“ Player”的游戏对象(飞机)的运动。

创建EasyTouch之后,我将创建一个C#脚本,如下所示:

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {
    public float m_speed = 1;

    protected Transform m_transform;

    public MovePlayer m_movePlayer;
    // Use this for initialization
    void Start () {
        m_transform = this.transform;
    }

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

    void OnEnable(){
        Debug.Log ("OnEnable");
        EasyJoystick.On_JoystickMoveStart += HandleOn_JoystickMoveStart;
        EasyJoystick.On_JoystickMove += HandleOn_JoystickMove;
        EasyJoystick.On_JoystickMoveEnd += HandleOn_JoystickMoveEnd;
    }

    void HandleOn_JoystickMoveStart (MovingJoystick move)
    {

    }

    void HandleOn_JoystickMoveEnd (MovingJoystick move)
    {
    }

    void HandleOn_JoystickMove (MovingJoystick move)
    {
        Debug.Log ("HandleOn_JoystickMove");

        if (m_transform == null) {
                m_transform = this.transform;
        }

        if (move.joystickName != "moveJoystick") {
            Debug.Log ("return");
            return;
        }

        float currentPositionX = this.gameObject.GetComponent<Transform> ().position.x;
        float currentPositionZ = this.gameObject.GetComponent<Transform> ().position.z;

        float joyPositionX = move.joystickAxis.x;
        float joyPositionY = move.joystickAxis.y;
        Debug.Log ("joyPositionX = " + joyPositionX + " joyPositionY = " + joyPositionY);

        float moveh = joyPositionX / 10;
        float movev = joyPositionY / 10;

        this.m_transform.Translate (new Vector3 (-joyPositionX/10, 0, -joyPositionY/10));
    }
}


当我开始游戏时,代码工作正常,飞机将得到控制。

然后,我通过GUI创建按钮。

单击该按钮时,将调用代码Application.LoadLevel(0),并且级别将重新启动。

但是在我调用Application.LoadLevel(0)重新启动游戏之后。
EasyTouch无法控制飞机,并显示错误消息:

MissingReferenceException: The object of type 'Player' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.


我不知道为什么“玩家”将为空。
“ Player”应该在调用Application.LoadLevel(0)之后初始化,不是吗?

最佳答案

前言

我从未使用过这个EasyTouch插件(很幸运?:D)。因此,我将对您在代码中看到的内容进行假设。如果我错了-对不起:)

回答

看一下这段代码:

void OnEnable(){
    Debug.Log ("OnEnable");
    EasyJoystick.On_JoystickMoveStart += HandleOn_JoystickMoveStart;
    EasyJoystick.On_JoystickMove += HandleOn_JoystickMove;
    EasyJoystick.On_JoystickMoveEnd += HandleOn_JoystickMoveEnd;
}


看来EasyJoystick是静态类。您正在这里订阅静态事件。然后,在调用Application.LoadLevel()后,将Player类的实例标记为已销毁。但是订阅不会随处可见,一旦EasyJoystick触发事件之一(On_JoystickMoveStartOn_JoystickMoveOn_JoystickMoveEnd),就会调用相应的方法(HandleOn_JoystickMoveStartHandleOn_JoystickMoveHandleOn_JoystickMoveEnd)。这就是为什么您会得到例外。它很可能被这一行抛出(我错了吗?:)):

float currentPositionX = this.gameObject.GetComponent<Transform> ().position.x;


为了解决此问题,您需要在调用Player之前取消预订Application.LoadLevel()实例的事件。

边注

这个:

float currentPositionX = this.gameObject.GetComponent<Transform> ().position.x;


可以重写为:

float currentPositionX = transform.position.x;


虽然currentPositionXcurrentPositionY根本不使用:D

编辑。如何退订

像这样:

void OnDisable(){
    Debug.Log ("OnDisable");
    EasyJoystick.On_JoystickMoveStart –= HandleOn_JoystickMoveStart;
    EasyJoystick.On_JoystickMove –= HandleOn_JoystickMove;
    EasyJoystick.On_JoystickMoveEnd –= HandleOn_JoystickMoveEnd;
}

10-04 19:00