假设我们需要自己用代码来设计游戏物体这样一个泛用的概念,学过面向对象编程的应该都会第一时间想起那个经典的例子:
// 基类是Person,代表所有子类都是人类
class Person {};
// Student继承自Person,可以带有Person的能力,又能有自己的特殊功能
class Student : public Person {};
// Doctor也是类似
class Doctor : public Person {};
这样设计的好处就是复用了子类可以复用父类的能力,还能利用多态对相同接口做出不同的响应,从而实现一些统一的封装逻辑。
对于一些方向,确实很好用,例如UI框架就是非常典型的可以一层一层继承下去的场景。
但是对于游戏,我们可以这样设想一下:
// 基类是GameObject,代表所有物体都是GameObject
class GameObject{};
// 立方体Cube继承自GameObject
class Cube : public GameObject {};
// 球形Sphere继承自GameObject
class Sphere : public GameObject {};
这样设计看起来好像也没啥问题,但是如果有这样的情况呢:
我自己是使用Rider的,因为真的更丝滑,并且支持代码里面显示资源引用代码的情况(默认情况只显示代码引用代码的情况),这对游戏开发来说非常实用。
当然我们新手教程下,用啥IDE都一样,就算用记事本也无所谓,这里我用rider作为示例,因为开发过程中并不需要碰编译或者编译配置,所以只做代码文件编写的话,不同IDE之间没有显著的使用区别。
这里我新建了一个DemoTest.cs文件,新建完成后双击打开后可以看到这样的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DemoTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
那么你会困惑GameObject又和组件代码的生命周期回调是个什么关系呢?其实就是GameObject才具有声明周期,而组件实际上是跟着GameObject一起调用声明周期回调。
现在我们给我们的组件加一点点小功能,在Start里面打印一句话:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DemoTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Debug.Log("Hello World!");
}
// Update is called once per frame
void Update()
{