0

ivがいくつかのことを理解しようとしているという問題があり、その原因を特定できないようです! 小さなマップ上の数人の敵で構成される一人称シューティング ゲームを作成しました。2 つのシーン (メイン メニューとゲーム レベル) があります。プレイヤーが死ぬと、メイン メニューが表示され、そこから再びゲームをプレイすることを選択できます。これにより、レベルが再度リロードされます。初めてゲームを実行すると、問題なく実行されます。ただし、ゲームのプレイボタンをもう一度押すと、「MissingReferenceException: タイプ 'GameObject' のオブジェクトが破棄されましたが、まだアクセスしようとしています。以下のコードから、GameObject の 2 つのタイプしか確認できません。それが問題であるかどうかを確認するためにマズルフラッシュを削除しようとしましたが、違いはありません. これが問題の原因である可能性があることを読んだので、すべての静的ボックスのチェックを外しましたが、これで問題は解決しませんでした。以下のスクリプトは敵にアタッチされています。FPS に PlayerShot スクリプトがアタッチされています。誰か助けてください。

// speed of the AI player
public var speed:int = 5;

// speed the ai player rotates by
public var rotationSpeed:int = 3;

// the waypoints
public var waypoints:Transform[];

// current waypoint id
private var waypointId:int = 0;

// the player
public var player:GameObject;

// firing toggle
private var firing:boolean = false;

// the Mesh Renderer of the Muzzle Flash GameObject
private var muzzleFlashAgent:GameObject;


/**
    Start
*/
function Start() 
{
    // retrieve the player
    player = GameObject.Find("First Person Controller");

    // retrieve the muzzle flash
    muzzleFlashAgent = GameObject.Find("muzzleFlashAgent");

    // disable the muzzle flash renderer
    muzzleFlashAgent.active = false;
}

/**
    Patrol around the waypoints
*/
function Patrol()
{
    // if no waypoints have been assigned
    if (waypoints.Length == 0) 
    {
        print("You need to assign some waypoints within the Inspector");
        return;
    }

    // if distance to waypoint is less than 2 metres then start heading toward next waypoint
    if (Vector3.Distance(waypoints[waypointId].position, transform.position) < 2)
    {
        // increase waypoint id
        waypointId++;

        // make sure new waypointId isn't greater than number of waypoints
        // if it is then set waypointId to 0 to head towards first waypoint again
        if (waypointId >= waypoints.Length) waypointId = 0;
    }

    // move towards the current waypointId's position
    MoveTowards(waypoints[waypointId].position);
}

/**
    Move towards the targetPosition
*/
function MoveTowards(targetPosition:Vector3)
{
    // calculate the direction
    var direction:Vector3 = targetPosition - transform.position;

    // rotate over time to face the target rotation - Quaternion.LookRotation(direction)
    transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);

    // set the x and z axis of rotation to 0 so the soldier stands upright (otherwise equals REALLY bad leaning)
    transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

    // use the CharacterController Component's SimpleMove(...) function
    // multiply the soldiers forward vector by the speed to move the AI
    GetComponent (CharacterController).SimpleMove(transform.forward * speed);

    // play the walking animation
    animation.Play("walk");
}


/**
    Update
*/
function Update()
{
    // calculate the distance to the player
    var distanceToPlayer:int = Vector3.Distance(transform.position, player.transform.position);

    // calculate vector direction to the player
    var directionToPlayer:Vector3 = transform.position - player.transform.position;

    // calculate the angle between AI forward vector and direction toward player
    // we use Mathf.Abs to store the absolute value (i.e. always positive)
    var angle:int = Mathf.Abs(Vector3.Angle(transform.forward, directionToPlayer));

    // if player is within 30m and angle is greater than 130 (IN FRONT) then begin chasing the player
    if (distanceToPlayer < 30 && angle > 130)
    {
        // move towards the players position
        MoveTowards(player.transform.position);

        // if not firing then start firing!
        if (!firing) Fire();
    }
    // if player is within 5m and BEHIND then begin chasing
    else if (distanceToPlayer < 5 && angle < 130)
    {
        // move towards the players position
        MoveTowards(player.transform.position);

        // if not firing then start firing!
        if (!firing) Fire();
    }
    else
    {
        // patrol
        Patrol(); 

        // stop firing
        firing = false;
    }
}

/**
    Fire at the player
*/
function Fire()
{
    // toggle firing on
    firing = true;

    // check if still firing
    while (firing)
    {
        // hit variable for RayCasting
        var hit:RaycastHit;

        // range of weapon
        var range:int = 30;

        // fire the ray from our position of our muzzle flash, forwards "range" metres and store whatever is detected in the variable "hit"
        if (Physics.Raycast(muzzleFlashAgent.transform.position, transform.forward, hit, range)) 
        {
            // draw a line in the scene so we can see what's going on
            Debug.DrawLine (muzzleFlashAgent.transform.position, hit.point);

            // if we hit the player
            if (hit.transform.name == "First Person Controller")
            {
                // inform the player that they have been shot
                player.GetComponent(PlayerShot).Shot();  

                // play gunshot sound
                audio.PlayOneShot(audio.clip);


                // show muzzle flash for X seconds
                muzzleFlashAgent.active = true;
                yield WaitForSeconds(0.05);
                muzzleFlashAgent.active = false; 

                // wait a second or two before firing again
                yield WaitForSeconds(Random.Range(1.0, 2.0));
            }
        }

        // wait till next frame to test again
        yield;
    }
}

これはゲームオブジェクトを破壊する PlayerShot です。

// the sound to play when the player is shot
public var shotSound:AudioClip;



// the number of lives
public var lives:int = 3;


/**
    Player has been shot
*/
function Shot () 
{
    // play the shot audio clip
    audio.PlayOneShot(shotSound);

    // reduce lives
    lives--;

    // reload the level if no lives left
    if (lives == 0)
    {
        // destroy the crosshair
        Destroy(GetComponent(CrossHair));


        // add the camera fade (black by default)
        iTween.CameraFadeAdd();

        // fade the transparency to 1 over 1 second and reload scene once complete
        iTween.CameraFadeTo(iTween.Hash("amount", 1, "time", 1, "oncomplete", "ReloadScene", "oncompletetarget", gameObject));
    }
}


/**
    Reload the scene
*/ 
function ReloadScene()
{
    // reload scene
    Application.LoadLevel("MainMenu");
}

BasicAI とともに敵に付属するスクリプトは、ゲームオブジェクトを破壊する SoldierShot Script です。以下はスクリプトです。

public var ragdoll:GameObject;

/**
    Function called to kill the soldier
*/
function Shot()
{
    // instantiate the ragdoll at this transform's position and rotation
    Instantiate(ragdoll, transform.position, transform.rotation);

    Destroy(GetComponent(BasicAI));
    // destroy the animated soldier gameobject
    Destroy(gameObject);

}
4

2 に答える 2

2

破棄されたゲームオブジェクトへの参照を保持しているようです (または、私は間違っていますか?)。

オブジェクトへの参照がある場合、一般的な C# (およびおそらく JavaScript) プログラムで発生することとは対照的に、Unity では、オブジェクトを破棄すると、オブジェクトへのすべての参照が に移動しnullます。

于 2012-04-19T03:16:37.730 に答える
1

簡単に修正できます。「ゲームレベル」でgameObjectを削除し、次の方法で兵士をその場でインスタンス化できます。

var instance : GameObject = Instantiate(Resources.Load("Soldier"));

プロジェクトフォルダにResourcesフォルダを作成し、はんだ用のプレハブをその中に入れるだけです。

于 2012-07-19T03:46:15.253 に答える