学习教程

https://learn.u3d.cn/tutorial/beginner-gameplay-scripting

笔记

Rigidbody.AddForce() 里的参数ForceMode

ForceMode说明效果举例
Force持续施加力(受质量影响)像风吹一样慢慢推动
Impulse瞬时冲击(受质量影响)像一拳打出去,一下飞走
VelocityChange瞬时改变速度(不受质量影响直接赋予速度,不管多重
Acceleration持续加速(不受质量影响)稳定加速

获取并开关组件

myLight = GetComponent<Light>();
myLight.enabled = !myLight.enabled;。//反转组件开关状态

对象开关

gameObject.SetActive(false);
myObject.activeSelf
myObject.activeInHierarchy //层级中

作用机制类似PS的图层可见性,设置父级整个组的可见性不影响子组件状态,但能整体调整

运动

transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);

摄像机LookAt

public class CameraLookAt : MonoBehaviour
{
    public Transform target;
    
    void Update ()
    {
        transform.LookAt(target);
    }
}

平滑旋转

Vector3 dir = target.position - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, Time.deltaTime * speed);

Quaternion 是四元数,用来表示旋转。

Quaternion.Lerp(a, b, t):从 a(当前朝向)慢慢旋转到 b(目标朝向),速度由 t 控制。

常用的内置方向(Unity 内置的 Vector3 常量):

方向含义等价于
Vector3.zero(0, 0, 0)原点
Vector3.one(1, 1, 1)所有分量都是 1
Vector3.up(0, 1, 0)向上
Vector3.down(0, -1, 0)向下
Vector3.left(-1, 0, 0)向左
Vector3.right(1, 0, 0)向右
Vector3.forward(0, 0, 1)向前(Z轴)
Vector3.back(0, 0, -1)向后

Lerp插值

Vector3 from = new Vector3 (1f, 2f, 3f);
Vector3 to = new Vector3 (5f, 6f, 7f);

// 此处 result = (4, 5, 6)
Vector3 result = Vector3.Lerp (from, to, 0.75f);

void Update ()
{
    light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f * Time.deltaTime);
}// 光强向8逼近,随时间平滑

SmoothDamp可以直接对值平滑

Vector3 SmoothDamp(
    Vector3 current, 
    Vector3 target, 
    ref Vector3 currentVelocity, 
    float smoothTime, 
    float maxSpeed = Mathf.Infinity, 
    float deltaTime = Time.deltaTime
)

Destroy

可以删除组件、对象

删除对象最好是建立一个public GameObject other;否则删自己会把绑定的脚本一块删了,变成一次性

Destroy(GetComponent<MeshRenderer>());

GetButton 和 GetKey

GetButton 方便适配多种控制器输入,GetKey(KeyCode.Q)仅获取键盘按键输入

Axis沿坐标轴运动

using UnityEngine;
using System.Collections;

public class DualAxisExample : MonoBehaviour 
{
    public float range;
    public GUIText textOutput;
    
    
    void Update () 
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        float xPos = h * range;
        float yPos = v * range;
        
        transform.position = new Vector3(xPos, yPos, 0);
        textOutput.text = "Horizontal Value Returned: "+h.ToString("F2")+"\nVertical Value Returned: "+v.ToString("F2");    
    }
}

Unity 内置的事件函数

函数说明
Awake()最早被调用,一般用于变量初始化
Start()在对象启用后第一次帧更新前调用
Update()每帧调用一次(逻辑处理)
FixedUpdate()每固定时间调用一次(物理计算)
LateUpdate()在所有 Update 调用完后执行,常用于摄像机跟随
OnEnable()物体启用时调用
OnDisable()物体被禁用时调用
OnDestroy()物体销毁时调用

3D 碰撞事件(适用于 Rigidbody + Collider):

函数说明
OnCollisionEnter(Collision col)碰撞开始时触发
OnCollisionStay(Collision col)持续碰撞时触发
OnCollisionExit(Collision col)碰撞结束时触发

3D 触发事件(Collider 设置为 isTrigger = true):

函数说明
OnTriggerEnter(Collider other)进入触发器区域时
OnTriggerStay(Collider other)停留在触发器区域内
OnTriggerExit(Collider other)离开触发器区域时

GetComponent

会消耗大量性能,在awake或者start里面使用

Time.deltaTime

让值相对时间平滑,而非根据帧率变动

Instantiate

拼好件,默认返回类型为object,可以强制转换为Rigidbody

Rigidbody rocketInstance;
            rocketInstance = Instantiate(rocketPrefab, barrelEnd.position, barrelEnd.rotation) as Rigidbody;
            rocketInstance.AddForce(barrelEnd.forward * 5000);

通过tag查找,塞进数组

public GameObject[] players;
players = GameObject.FindGameObjectsWithTag("Player");

定时执行函数:Invoke

Invoke ("SpawnObject", 2);
// SpawnObject返回类型必须为void且无传参

枚举

enum Direction {North, East, South, West};

Direction myDirection;
        
myDirection = Direction.North;

中级C#教学

https://learn.u3d.cn/tutorial/intermediate-gameplay-scripting

属性

public int Health{ get; set;}
自动实现私有变量和对应的get和set

事件

// EventManager
using UnityEngine;
using System.Collections;

public class EventManager : MonoBehaviour 
{
    public delegate void ClickAction();
    public static event ClickAction OnClicked;


    void OnGUI()
    {
        if(GUI.Button(new Rect(Screen.width / 2 - 50, 5, 100, 30), "Click"))
        {
            if(OnClicked u0021= null)
                OnClicked();
        }
    }
}
// TeleportScript
using UnityEngine;
using System.Collections;

public class TeleportScript : MonoBehaviour 
{
    void OnEnable()
    {
        EventManager.OnClicked += Teleport;//从事件中订阅方法
    }


    void OnDisable()
    {
        EventManager.OnClicked -= Teleport;
    }


    void Teleport()
    {
        Vector3 pos = transform.position;
        pos.y = Random.Range(1.0f, 3.0f);
        transform.position = pos;
    }
}

扩展

ExtensionMethods
using UnityEngine;
using System.Collections;

//创建一个包含所有扩展方法的类
//是很常见的做法。此类必须是静态类。
public static class ExtensionMethods
{
    //扩展方法即使像普通方法一样使用,
    //也必须声明为静态。请注意,第一个
    //参数具有“this”关键字,后跟一个 Transform
    //变量。此变量表示扩展方法会成为
    //哪个类的一部分。
    public static void ResetTransformation(this Transform trans)
    {
        trans.position = Vector3.zero;
        trans.localRotation = Quaternion.identity;
        trans.localScale = new Vector3(1, 1, 1);
    }
}

给Transform添加了一个方法,可以用tran.ResetTransformation()

幾重にも辛酸を舐め、七難八苦を越え、艱難辛苦の果て、満願成就に至れ
最后更新于 2025-04-12