【问题标题】:How to avoid type checking every frame?如何避免每帧都进行类型检查?
【发布时间】:2019-11-22 15:28:21
【问题描述】:

我正在编写一个车辆控制器,它应该能够处理多种不同的车辆类型,而不是使用继承,因此我可以将类的数量保持在最低限度。我想删除检查每个固定帧的常量类型,但我不知道该怎么做。

private void FixedUpdate()
{
    if (VehicleSchema is VehicleSchema_AFV.Hovercraft)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(false, false);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
    else if (VehicleSchema is VehicleSchema_AFV.Wheeledcraft)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(true);
        AlignToTerrain(true, true);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
    else if (VehicleSchema is VehicleSchema_AFV.Trackedcraft)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(true, false);

        VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
        UpdateTurretRotation(afv.TurretObj);
    }
    else if (VehicleSchema is VehicleSchema_Mech)
    {
        UpdatePosition(transform.forward, false);
        UpdateYawRotation(false);
        AlignToTerrain(true, false);

        VehicleSchema_Mech mech = (VehicleSchema_Mech)VehicleSchema;
        UpdateTurretRotation(mech.TorsoObject);
    }
    else if (VehicleSchema is VehicleSchema_Aircraft.VTOL)
    {
        UpdatePosition(transform.up, true);
        UpdateYawRotation(false);
        UpdatePitchRotation();
        UpdateRollRotation();

        VehicleSchema_Aircraft.VTOL vtol = (VehicleSchema_Aircraft.VTOL)VehicleSchema;
        UpdateTurretRotation(vtol.TurretObj);
    }
}

【问题讨论】:

    标签: c# unity3d types


    【解决方案1】:

    使用一些多态性怎么样?

    只需声明一个代表可更新车辆的接口

    interface IUpdatableVehicle
    {
        void Update();
    }
    

    然后让你的类用各自的逻辑实现这个接口

    class Hovercraft : IUpdatableVehicle
    {
        public void Update()
        {
            UpdatePosition(transform.forward, false);
            UpdateYawRotation(false);
            AlignToTerrain(false, false);
    
            VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
            UpdateTurretRotation(afv.TurretObj);
        }
    }
    
    class Wheeledcraft : IUpdatableVehicle
    {
        public void Update()
        {
            UpdatePosition(transform.forward, false);
            UpdateYawRotation(true);
            AlignToTerrain(true, true);
    
            VehicleSchema_AFV afv = (VehicleSchema_AFV)VehicleSchema;
            UpdateTurretRotation(afv.TurretObj);
        }
    }
    
    // And so on ...
    

    最后,在更新函数中使用一条指令

    private void FixedUpdate(IUpdatableVehicle vehicle) {
        vehicle.Update();
    }
    

    现在,如果UpdatePositionUpdateYawRotation 等在其上下文之外可用(我不熟悉 Unity)或者您是否可以访问基类,那么最初的问题并不准确,所以我假设是这种情况。如果不是,您可能希望在原始问题中添加这些精度。

    【讨论】:

    • 感谢 Arthur 抽出宝贵时间,非常感谢! UpdatePosition()、UpdateRotation() 等是我自己在 VehicleController 类中用来实际移动对象的方法。我从来没有想过按照你描述的方式做这件事,所以我认为你让我打开了一个全新的世界。我很惊讶我不必做一些疯狂的继承。我特别想避免每次在游戏中添加新车辆时都必须制作新控制器,这几乎解决了这个问题。现在我可以只调整车辆类本身,而不必担心控制器
    【解决方案2】:

    再次感谢 Arthur 帮助解决此问题。由于我的程序结构,我不得不稍微修改 Arthur 的解决方案以使其正常工作。但是,如果他们在旅途中遇到这样的事情,我想为其他人发帖。

    界面

    public interface IUpdatableVehicle
    {
        void UpdateWorldState();
    }
    

    基类

    public abstract class VehicleSchema : MonoBehaviour, IUpdatableVehicle
    {
    
    //Properties
    //========================================================================================================================//
    
    public VehicleController VehicleCtrler { get; protected set; }
    
    //Methods
    //========================================================================================================================//
    
    private void Awake()
    {
        VehicleCtrler = gameObject.AddComponent<VehicleController>();
        gameObject.AddComponent<VehicleInputController_Player>();
    }
    
    //Abstract Methods
    //========================================================================================================================//
    
    public abstract void UpdateWorldState();
    }
    

    子类

    public abstract class VehicleSchema_AFV : VehicleSchema
    {
    
    //Sub AFV Classes
    //========================================================================================================================//
    
    public abstract class Hovercraft : VehicleSchema_AFV
    {
        public override void UpdateWorldState()
        {
            VehicleCtrler.UpdatePosition(transform.forward, false);
            VehicleCtrler.UpdateYawRotation(false);
            VehicleCtrler.AlignToTerrain(false, false);
    
            VehicleCtrler.UpdateTurretRotation(TurretObj);
        }
    }
    
    public abstract class Trackedcraft : VehicleSchema_AFV
    {
        public override void UpdateWorldState()
        {
            VehicleCtrler.UpdatePosition(transform.forward, false);
            VehicleCtrler.UpdateYawRotation(false);
            VehicleCtrler.AlignToTerrain(true, false);
    
    
            VehicleCtrler.UpdateTurretRotation(TurretObj);
        }
    }
    
    public abstract class Wheeledcraft : VehicleSchema_AFV
    {
        public override void UpdateWorldState()
        {
            VehicleCtrler.UpdatePosition(transform.forward, false);
            VehicleCtrler.UpdateYawRotation(true);
            VehicleCtrler.AlignToTerrain(true, true);
    
            VehicleCtrler.UpdateTurretRotation(TurretObj);
        }
    }
    

    }

    控制器

    [RequireComponent(typeof(Rigidbody))]
    public class VehicleController : MonoBehaviour
    {
    
    //Properties
    //========================================================================================================================//
    
    public VehicleSchema VehicleSchema { get; protected set; }
    
    //Methods
    //========================================================================================================================//
    
    private void FixedUpdate()
    {
        VehicleSchema.UpdateWorldState();
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-20
      • 1970-01-01
      • 2013-11-08
      • 2021-07-28
      • 1970-01-01
      相关资源
      最近更新 更多