学习教程
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()
Comments NOTHING