From:Unity官网C#初级编程
Unity官网C#中级编程
脚本 Scripts 作为 behavior component (行为组件),用于 Object,不同对象的不同行为
Start & Awake
Awake
Start
初始化之前,脚本不启用也会初始化
Awake 之后,首次 Updata 之前,脚本启用才会初始化
Public & Private & Protected
Public
Private
Protected
类外(其他脚本)可以访问
只允许类内访问,默认私有
允许子类访问
Updata & FixedUpdata
Updata
FixedUpdata
使用的脚本每帧调用一次,调用间隔不同,非物理相关
固定时间,间隔相同调用,每秒调用50次,用于物理(Rigibody)相关函数,力相关
1 2 3 4 5 6 7 8 9 private void Update (){ Debug.Log("Updata Time: " + Time.deltaTime); } private void FixedUpdate (){ Debug.Log("FixedUpdata Time: " + Time.deltaTime); }
1 2 3 #结果 Updata Time: 0.0023467 0.0023239 …… FixedUpdata Time: 0.02 0.02 0.02 ……
DeltaTime
Time 类的 DeltaTime 用于计算两次更新或固定函数调用的间隔时长,用于移动或其他增量变化变得平滑
因为完成一帧的时长是不一致的,按完成每帧做速率会不平滑
Speed * Time.deltaTime 用于速率恒定
Invoke
延迟执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public GameObject target;void Start (){ Invoke("SpawObject" , 2 ); InvokeRepeating("SpawObject" , 2 , 1 ); CancelInvoke("SpawObject" ); } void SpawObject (){ float x = Random.Range(-2f , 2f ); Instantiate(target, new Vector(0 , 2 , 0 ), Quaternion.identity); }
点积 & 叉积
Dot 点积
Cross 叉积
计算得到数值,==0为垂直,可用于飞机飞行方向判断
计算得到矩阵,可用于炮塔朝向
Vector3. Dot (VectorA, VectorB)
Vector3. Cross (VectorA, VectorB)
启动组件
Inspector 窗口 ->组件前面的勾
1 Component.enabled = false or true ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class LightEnable : MonoBehaviour { private Light pointLight; void Start () { pointLight = GetComponent<Light>(); } void Update () { if (Input.GetKeyUp(KeyCode.Space)) pointLight.enabled = false ; } }
启用对象
Hierarchy 窗口 -> GameObject 是否开启
1 >gameObject.SetActive(false );
Translate & Rotate
平移和旋转:针对局部坐标(Local axis)
Vector3. forward and Vector3. Up 都是局部坐标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class TransformObject : MonoBehaviour { public float moveSpeed = 10f ; public float turnSpeed = 50f ; void Update () { if (Input.GetKey(KeyCode.UpArrow)) transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed); if (Input.GetKey(KeyCode.DownArrow)) transform.Translate(-Vector3.forward * Time.deltaTime * moveSpeed); if (Input.GetKey(KeyCode.LeftArrow)) transform.Rotate(Vector3.up, -turnSpeed * Time.deltaTime); if (Input.GetKey(KeyCode.RightArrow)) transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime); } }
LookAt
GameObject 的 forward 指向世界坐标(World axis)的另一个transform
1 2 3 4 5 6 7 # 摄像机看向目标 Transform target; void Update () { transform.LookAt(target); }
Destory 1 2 3 # 销毁对象or组件,第二个参数为延时(delay) Destory(GameObject, 3f ); Destory(GetComponent<MeshRenderer>());
OnMouseDown 1 2 3 4 5 # 判断鼠标点击 void OnMouseDown (){ rb.AddForce(-transform.forward * 500f ); }
Class
面向对象编程:将脚本拆分成多个脚本,每一个脚本承担一个角色或指责
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public Class School: MonoBehavior{ public int studentCout; public int teacherCout; public int bookCout; public float avgNum; public School (int a, int b, int c ) { studentCout = a; teacherCout = b; bookCout = c; } public School (int a, float avg ) { student = a; avgNum = avg; } public School () { studentCout = 1 ; teacherCout = 1 ; bookCout = 1 ; } public School dogSchool = new School(10 , 100 , 1000 ); public School catSchool = new School(20 , 50.5f ); }
Instantiate
Instantiate 用于克隆 gameObject,常用于克隆 Prefabs,即预配置对象
例如抛射出的物体
1 2 >Instantiate(object ); >Instantiate(object , position, rotation);
数组 1 2 3 4 5 6 int [] myIntArray = new int [3 ];myIntArray[0 ] = 1 ; myIntArray[1 ] = 2 ; myIntArray[2 ] = 3 ; int [] myInyArray = {1 , 2 , 3 };
枚举
列出枚举值,定义变量,选择枚举值给变量赋值
1 2 3 4 5 6 7 enum Direction {North, East, South, West}; Direction myDirection; void Start (){ myDirection = Directio.North; }
Switch
更简洁的选择语句,避免选择多时代码变得冗长
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class SwitchText : MonoBehaviour { public int intelligence = 5 ; void Greet () { switch (intelligence) { case 5 : print("Nice to meet u!" ); break ; case 4 : print("Hello!" ); break ; case 3 : print("ababababa" ); break ; case 2 : print("0100010010" ); break ; default : print("Aroha!" ); break ; } } }
属性
对私有变量建立属性,其他类可以通过属性访问
通过 get 和 set 的保留设置只读或只写
可以当做函数使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Player : MonoBehaviour { private int experience; public int Experience { get { return experience; } set { experience = value ; } } public int Health { get ; set ; } }
1 2 3 4 5 6 7 8 void Start (){ Player myPlayer = new Player(); myPlayer.Experience = 5 ; int x = myPlayer.Experience; }
三目运算符
简答的 if-else 关系,执行内容短
1 2 3 4 int health = 10 ;string messing;messing = health > 0 ? "Player is alive" : "Player is dead" ;
Static 静态
跨类所有成员共享的成员,无需实例化,一个类中静态成员值一样,不可以包含非静态成员
静态方法属于类,非静态方法属于类的实例
1 2 3 4 5 6 7 # 计算生成实例 Enemy 数量 public class Enemy { pubic Static int enemyCout = 0 ; public Enemy{ enemyCout++ }; }
1 2 3 4 5 6 7 8 9 10 11 public class Game { void Start () { Enemy enemy1 = new Enemy(); Enemy enemy2 = new Enemy(); Enemy enemy3 = new Enemy(); int x = Enemy.enemyCout; } }
泛型
GetComponent<> 泛型方法,T 表示任何类型
所有 C# 类隐式从基类继承而来
1 2 3 4 5 6 7 8 9 public class SomeClass { public T GenericMethod <T >(T param ) where T: class { return param; } }
1 2 3 4 5 6 7 8 9 # 调用 public class SomeOtherClass { void start () { SomeClass myclass = new SomeClass(); myclass.GenericMethod<int >(5 ); } }
继承
MonoBehaviour 类有 start、updata 等函数
eg:BoxCollider 是 Collider 的子类,BoxCollider 是 Collider
子类调用的父类构造函数是固定的,base()
1 2 3 4 public class Scripts : MonoBehaviour { } public class Scripts
Overriding
更改子类中父类的方法
子类中创建函数,两个子类用的父类函数功能不一样
覆盖父类函数且保留方法的父版本
1 2 3 4 5 6 7 8 9 # 父类 virtual public class Humanoid (){ public virtual void Yell () { } }
1 2 3 4 5 6 7 8 9 # 派生类1 public class Enemy : Humanoid { public override void Yell () { base .Yell(); } }
1 2 3 4 5 6 7 8 9 # 派生类2 public class Orc : Enemy { public override void Yell () { base .Yell(); } }
接口
实现接口的任何类,必须拥有其所有方法和属性
用于跨多个互不相关的类定义通用功能(继承同一父类没有意义,用接口销毁所有更有效)
类外声明,一般一个接口一个文件,直接调用实现,不能生成实例,类要声明接口中的函数
通常大写 I 开头作为接口名字
1 2 3 4 5 6 7 8 9 # Interface public interface Ikillable { void Kill () ; } public interface IDamagable <T > { void Damage (T damageTaken ) ; }
函数主体与接口互相独立
1 2 3 4 5 6 7 8 9 10 11 12 # Avatar public class Avatar : MonoBehavior , Ikillable , IDamagable <float > { void Kill () { } void Damage (float damageTaken ) { } }
Extension Methods
用于需要向类添加功能,但不能编辑类
eg:transform 类不能修改源代码
1 2 3 4 5 6 7 8 9 10 # Extension Methods 扩展transform的方法,初始化transform的要求值 public static class ExtensionMethod { public static void ResetTransformation (this Transform trans ) { trans.position = Vector3.zero; trans.localRotation = Quanternion.identity; trans.localScale = new Vector3(1 , 1 , 1 ); } }
1 2 3 4 5 6 7 8 # SomeClass public class SomeClass : Monobehaviour { void start () { transform.ResetTransformation(); } }
命名空间
NameSpace 就像类的容器
1 2 3 using System.Collections;using System.Collections.Generic;using UnityEngine;
列表和字典
list 是泛型类
列表对象. Add(添加) Remove(移除) Insert(插入) Sort(排序)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # BadGuy public class BadGuy : IComparable <BadGuy >{ public string name; public int power; public BadGuy (string newName, int newPower ) { name = newName; power = newPower; } public int CompareTo (BadGuy other ) { if (other == null ) return 1 ; return power - other.power; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # SomeClass 创建列表 public class SomeClass : MonoBehaviour { void Start () { List<BadGuy> badguys = new List<BadGuy>(); badguys.Add(new BadGuy("Harry" , 50 )); badguys.Add(new BadGuy("Pip" , 10 )); badguys.Add(new BadGuy("Tom" , 100 )); badguys.Sort(); foreach (BadGuy guy in badguys) print(guy.name + " " + guy.power); badguys.Clear(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class SomeClass : MonoBehaviour { void Start () { Dictionary<string , BadGuy> badguys = new Dictionary<string , BadGuy>(); BadGuy bg1 = new BadGuy("Harry" , 10 ); BadGuy bg2 = new BadGuy("Tom" , 20 ); badguys.Add("Marry" , bg1); badguys.Add("Jerry" , bg2); } }
协程
Coroutines,Yield 执行,IEnumerator 返回
按时间间隔执行的函数
IEnumerator 不是 IEnumerable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class SomeClass : MonoBehaviour { public float smoothing = 1f ; public Transform target; void Start () { StartCoroutine(MyCoroutine(target)); } IEnumerator MyCoroutine (Transform target ) { while (Vector3.Distance(transform.position, target.position) > 0.05f ) { transform.position = Vector3.Lerp(transform.position, target.position, smoothing * Time.deltaTime); yield return null ; } print("Reach the Target!" ); yield return new WaitForSeconds (3f ) ; print("MyCoroutine is finished!" ); } }
四元数
Quaternions:x,y,z,w
欧拉角:围绕 x,y,z 轴旋转
1 2 3 4 5 6 7 8 9 Vector3 relativePos = target.position - transform.position; Quaternion rotation = Quaternion.LookRotation(relativePo); Quaternion current = transform.localRotation; transform.localRotation = Quaternion.slerp(current, rotation, Time.deltaTime); transform.rotation = Quaternion.identity;
委托
Delegates
看做存放函数的容器的变量,处理复杂行为,同时控制多个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class DelegateTest : MonoBehaviour { delegate void MultiDelegate () ; MultiDelegate multiDelegate; void Start () { multiDelegate += PowerUp; multiDelegate += TurnRed; if (multiDelegate != null ) multiDelegate(); } void PowerUp () { print("Orb is Up!" ); } void TurnRed () { GetComponent<Renderer>().material.color = Color.red; } }
事件
Events 特殊委托,方法(函数)定位到事件
通过 OnEnable += 将方法订阅到事件,在发生事件时可以调用方法
通过 OnDisable -= 将方法退订,在事件销毁时停用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # EventManager 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 != null ) OnClicked(); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class TurnColor : MonoBehaviour { void OnEnable () { EventManager.OnClicked += Turn; } void OnDisable () { EventManager.OnClicked -= Turn; } void Turn () { Color col = new Color(Random.value , Random.value , Random.value ); GetComponent<Renderer>().material.color = col; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class TeleporScripts : MonoBehaviour { private void OnEnable () { EventManager.OnClicked += Teleport; } private void OnDisable () { EventManager.OnClicked -= Teleport; } void Teleport () { Vector3 pos = transform.position; pos.y = Random.Range(.3 f, 1.0f ); transform.position = pos; } }
鼠标点击按钮,两个事件同时触发
特性 1 2 3 4 5 6 7 8 9 10 [ExecuteEditMode ] public class SpinScript : Monobehaviour { [Range(-100, 100) ] public float speed = 0 ; [Header("Player" ) ] GameObject player; }
Print & Debug.log
两者都输出到 Console 控制台,属于 UnityEngine 命名空间
Debug 是一个密闭的类, Print 是 MonoBehaviour 的一个成员,print 就是 Debug.Log 的一个简单封装
1 2 3 4 5 6 7 8 9 10 using UnityEngine;public class OutPut : Monobehaviour { void start () { print("test Print" ); Debug.log("test Debug" ); } }
From:https://blog.csdn.net/qq_42351033/article/details/83990499