C# 共有财产;字段继承

C# 共有财产;字段继承,c#,unity3d,inheritance,C#,Unity3d,Inheritance,我一直在尝试在不同的类中完美地构建这个项目,同时最大化继承的好处。然而,到目前为止,它给我带来的麻烦多于好处 考虑这一点: public class SuperClass : MonoBehaviour { [SerializeField] protected Camera _camera; } 还有这个 public class SubClass : SuperClass { } 这两个脚本都附加到场景中的不同游戏对象 通过在“检查器”中拖动摄影机来指定摄影机 我尝试了这个,

我一直在尝试在不同的类中完美地构建这个项目,同时最大化继承的好处。然而,到目前为止,它给我带来的麻烦多于好处

考虑这一点:

public class SuperClass : MonoBehaviour
{
    [SerializeField] protected Camera _camera;
}
还有这个

public class SubClass : SuperClass
{

}
  • 这两个脚本都附加到场景中的不同游戏对象
  • 通过在“检查器”中拖动摄影机来指定摄影机
我尝试了这个,unity似乎告诉我,我必须将相机分配给超类游戏对象和子类游戏对象,这对我来说毫无意义

如何将摄像头分配给SuperClass.cs,然后由其所有子类使用和共享?


提前谢谢

您需要在某个地方创建公共静态摄影机属性,并在代码中引用它,使用属性:

public static class StaticValues
{
    public static Camera Camera {get; set;} 
}
public class SuperClass : MonoBehaviour
{
    [SerializeField] protected Camera _camera
    {
        get
        {
            return StaticValues.Camera;
        }
        set
        {
            StaticValues.Camera = value;
        }
    }
}
public class SubClass : SuperClass
{

}
由其所有子类共享

类共享只能通过使用“静态”(静态变量或单例)实现

解决办法可能是

public class SubClass :SuperClass 
{
     [SerializeField] Camera camera;

     void Awake()
     {
         if(camera!=null)
         {
             _camera=camera;
         }
     }

    // Start is called before the first frame update
    void Start()
    {
        camera=_camera;
    }
}

要进一步扩展该解决方案,您可以编写一个编辑器脚本,或者只从代码中获取相机。

受保护的
修改为
公共的
这是两个不同的实例,还是只有一个?如果它是同一个实例,并且您能够成功地将摄影机作为超类指定给对象,那么它应该可以正常工作。如果它们是不同的实例,继承对您没有帮助——每个实例都需要自己的赋值。有一种方法可以解决这个问题(使用
static
成员,可能是由实例属性指定的),但这是一种稍微不同的解决方案。@DominicP我尝试过各种方法,静态字段就是其中之一。对我来说,这些静态字段的问题是,它们不会出现在检查器中。我真的不想为此编写我自己的自定义编辑器。你可以使用一个静态字段和一个非静态属性的组合<代码>静态摄像机后跟
public/*non-static*/Camera-Camera{get{return-Camera;/*返回共享的静态实例*/}set{Camera=value;/*设置静态实例*/}
@DominicP我也试过了,我的unity inspector中没有显示“Camera”。我对您使用的一些代码不熟悉,所以我很感兴趣。首先,我想说的是,我的IDE告诉我,[serializefield]只能应用于字段而不能应用于属性,因此它不会显示在检查器中。据我所知,如果财产从一开始就公开,它也不会出现在检查员中。你能详细解释一下代码的其余部分吗?我以前从未在方法上使用过这种继承类型的东西(:base)。那里发生了什么事?你在利用构造器吗?我不认为它们在MonoBehavior中使用。自从我收到警告消息告诉我MonoBehavior不应该用关键字“new”实例化后,我就没有接触过MonoBehavior构造函数。但也许我认为单行为不使用构造函数是错误的,因为这不是一个大问题,你可以使用字段,如果你想的话,这里没有区别。同样,使用:base的这种构造被称为“c#构造函数继承”,这意味着当您创建类“SubClass”的实例时,该类具有字段“camera”,您只需在那里调用基类的构造函数(超类),将摄影机对象传递到那里。我已将上面的代码应用到我的代码中,并在摄影机上获得一个null引用。为了验证,我放置了一个Debug.Log()超类构造函数中的语句,它没有被打印出来,所以构造函数没有被调用。来自非单行为环境和java,这让我感到困惑,我想这就是为什么我过去避免在单行为中使用构造函数的原因。它是否对你有效,我是否遗漏了什么?只是做了一些进一步的研究h、 正如我所想,你在互联网上到处都能看到,在单行为脚本中永远不应该调用构造函数。我以前尝试过单体模式作为解决问题的方法,我在创建从通用单体类继承的单体时得到了最好的结果。但我最终没有使用它,因为在我的例子中,子类已经从另一个类继承,所以我无法使它也从通用的singleton类继承。在您的示例中,如何在其中一个子类中创建摄影机使其被所有子类共享?我猜这是一个拼写错误,但我想先问一下。@Thrindil只需将摄影机拖动到子类的一个实例。点击“播放”按钮后n、 子类的所有实例将自动共享它。(检查检查器)。不幸的是,这也不起作用。当我将相机拖动到子类的一个实例时,它确实会被分配到该实例,但不会自动分配到子类的其他实例。我想我必须学习如何使用可编写脚本的对象,以便为这个问题找到一个适当的、充实的解决方案。@Thrindil你是否按了“运行”按钮在运行时将摄像头分配给所有实例。如果你想在编译时执行,那么你应该深入研究编辑器脚本。不过,我认为从代码中获取摄像头是一种简单的方法。或者,如果你决定在运行时执行此操作,你可以让摄像头使用GameObject查找或其他类似的方法。我编辑了代码,等待unity刷新,然后拖拽将摄影机切换到子类的一个实例,点击“播放”按钮,注意到只有子类的一个实例分配了摄影机。其余的实例在inspector中的摄影机字段中为“无”。可能是因为在我的场景中,超类本身也有一个实例,但我认为这不应该是一个问题。