簡體   English   中英

在 Unity C# 腳本中未調用覆蓋虛擬函數

[英]Overriding virtual function not get called in Unity C# script

我在 Unity 3D、 PhysicsObjectPlayerPlatformerController編寫了以下 2 個腳本(遵循本教程)。 PlayerPlatformerController腳本附加到游戲對象。

物理對象.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhysicsObject : MonoBehaviour {
    void Update () {
        ComputeVelocity ();
    }

    protected virtual void ComputeVelocity() {

    }
}

玩家平台控制器.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerPlatformerController : PhysicsObject {
    void Update () {

    }

    protected override void ComputeVelocity() {

    }
}

該代碼看起來很簡單,但ComputeVelocity()PlayerPlatformerController不會被調用(通過添加證明Debug.Log() 為什么?

如果我更改為以下代碼,則該功能可以完美運行:

物理對象.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhysicsObject : MonoBehaviour {
    void Update () {
        //ComputeVelocity ();
    }

    /*protected virtual void ComputeVelocity() {

    }*/
}

玩家平台控制器.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerPlatformerController : PhysicsObject {
    void Update() {
         ComputeVelocity();
    }

    void ComputeVelocity() {

    }
}

我錯過了什么?

我碰巧有兩個腳本: Health.cs HealthModified.cs -> 這是 Health.cs 的覆蓋功能

在我的游戲對象中,我正在測試 HealthModified(啟用),並且游戲對象中還有 Health.cs 但已禁用。

代碼在禁用時也使用了 Halth.cs 組件,我必須從游戲對象中刪除該組件才能獲得 HealthModified 行為。

這可能是因為您在子類(PlayerPlatformerController)中使用了 Update 方法。 如果為真,您會將更新標記為受保護和虛擬,並在子類中覆蓋它。 它可能看起來像這樣:

public class PhysicsObject : MonoBehaviour
{
    protected virtual void Update()
    {
        ComputeVelocity();
        Debug.LogFormat("PhysicsObject Update");
    }

    protected virtual void ComputeVelocity()
    {
        Debug.LogFormat("PhysicsObject ComputeVelocity");
    }
}


public class PlayerPlatformerController : PhysicsObject
{
    protected override void Update()
    {
        base.Update();
        Debug.LogFormat("PlayerPlatformerController Update");
    }

    protected override void ComputeVelocity()
    {
        base.ComputeVelocity();
        Debug.LogFormat("PlayerPlatformerController ComputeVelocity");
    }
}

我終於發現了問題所在。 PlayerPlatformerController類中,如果我刪除Update()方法,則覆蓋ComputeVelocity()將開始工作。

感謝大家為我所做的努力。

當您有一個繼承自另一個類的類時,您需要警惕意外覆蓋父類的方法。

在這種情況下,創建空的 Start() 和 Update() 方法將替換來自父級的方法。 這是一個容易犯的錯誤,因為默認情況下通常使用這些方法創建新類。

從子類中刪除方法將確保調用父類。 或者,如果您想在調用父方法的同時保留子方法,則可以使用base.Start() (或您要覆蓋的任何方法)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM