Unity脚本
official::Unity 脚本 API
VS提取方法:Ctrl + R && Ctrl + M
一、基本概念
定义:脚本是附加在游戏物体上用于定义游戏对象行为的指令代码。
添加:
文件名必须与类名一致。
写好的脚本必须附加到物体上才执行。
附加到游戏物体的脚本类必须从MonoBehaviour类继承。
编译:源代码( CLS ) -> 中间语言( Mono Runtime )(中间产物是 .dll ) -> 机器码。
二、脚本 1 脚本操作 1.1 新建脚本默认
注意:
在 Unity 中,默认情况下,脚本是没有命名空间的。这意味着在编写脚本时,不需要显式地添加命名空间声明,因为 Unity 编辑器会自动将所有位于 “Assets” 文件夹下的脚本视为全局命名空间下的一部分。
例如,如果你在 Unity 中创建了一个名为 “PlayerController.cs” 的脚本,并且该脚本位于 “Assets/Scripts” 文件夹中,那么在该脚本中可以直接访问和使用其他位于 “Assets/Scripts” 文件夹中的脚本,而无需添加额外的命名空间声明。
这种做法简化了 Unity 中脚本的编写和管理,但也可能导致命名冲突或代码整理不够清晰。因此,一些开发人员仍然选择在脚本中显式添加命名空间声明,以确保代码的可维护性和可扩展性。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class NewBehaviourScript : MonoBehaviour { void Start () { } void Update () { } }
1.2 修改新建默认
默认模板存放位置:Unity\2021.3.5f1c1\Editor\Data\Resources\ScriptTemplates
1.3 开发工具设置
Edit——Preferences——External Tools——External Script Editor
1.4 脚本辅助操作
在Unity中,[RequireComponent]
是一个属性(Attribute),它用于确保一个MonoBehaviour脚本所附加的游戏对象上还存在其他指定的组件。当你在脚本类定义上方使用 [RequireComponent]
属性时,Unity引擎会自动检查并确保在运行时该游戏对象上存在指定的组件。如果没有,Unity会自动为游戏对象添加缺失的组件。
[RequireComponent(typeof(MyScript)) ]
2 脚本生命周期
official::脚本API
脚本生命流程图
函数执行顺序
阶段
作用
Awake
物体初始化阶段
赋值
OnEnable
物体初始化阶段
赋值
Start
物体初始化阶段
赋值
FixedUpdate
物理计算阶段
物理物件计算
OnTriggerEnter
物理计算阶段
物理物件计算
OnCollisionEnter
物理计算阶段
物理物件计算
Update
游戏过程计算阶段
计算更新
LateUpdate
游戏过程计算阶段
Camera
OnDisable
物体退出阶段
禁用事件
OnDestroy
物体退出阶段
销毁事件
2.1 格式
类:字段+方法。
属性:一般不写。(编辑器中无法普通显示)
构造函数:不写。
2.2 字段
public
会显示可重新赋值。(要隐藏在字段上一行加上 [HideInInspector]
)
private
不会显示。(要显示需要在字段上一行加上 [SerializeField]
)
[SerializeField]
:(序列化字段)在编辑器中显示私有变量。(可以重新赋值)
[HideInInspector]
:(隐藏检查器)在编辑器中隐藏公有变量。
[Range(n,m)]:限定数字范围为[n,m]
2.3 方法 private void Awake () ;private void Start () ; private void OnEnable () ;private void FixedUpdate () ;private void Update () ;private void LateUpdate () ;OnMouseEnter(); OnMouseOver(); OnMouseExit(); OnMouseDown(); OnMouseUp(); OnBecameVisible(); OnBecameInvisible(); OnDisable(); OnDestroy(); OnApplicationQuit();
3 调试
C#逆向工具ILspy:Library——ScriptAssemblies——脚本中间语言存储位置
控制台调试:
Windows——General——Console
Collapse:折叠相同项。
VS调试:
F12——找到方法源头
VS断点——VS启动调试——Unity开始游戏——回到VS中调试
调试——窗口——即时调试 / 自动调试 / 监视
Debug.Log("" ); Debug.LogFormat("" ); print(); Debug.DrawLine(a,b); private void OnDrawGizmos (){ Gizmos.DrawLine(transform.position, new Vector3(transform.position.x, transform.position.y - groundCheckDistance)); }
4 核心类图 三、常用API 1 Component
查找(在当前物体、后代、先辈)组件的功能。
this.GetComponent<name>()
:其他组件
获取所有组件名
var comp = this .GetComponents();foreach (var i in comp){ Debug.Log(i); }
获取父子组件
var comp = this .GetComponentsInParent<MeshRenderer>();var comp = this .GetComponentsInChildren<MeshRenderer>();
查找(父、根、子)变换组件,改变对象的位置、旋转、缩放比例。
属性
this .transform.position;this .transform.localPosition;this .transform.childCount;
方法
this .transform.translate(x,y,z,space);this .transform.Rotate(x,y,z,space);this .transform.transform.RotateAround(point,axis,angle);worldPosition = this .transform.TransformPoint(x, y, z); this .transform.LookAt(Vector3);
获取父子物体的transform
foreach (Transform child in this .transform);this .transform.root;this .transform.parent;this .transform.setParent(transform , worldposition);this .transform.Find("child's name [ / child's name ... ]" );for (int i=0 ; i < this .transform.childCount ; i++ ) Transform tf = this .transform.GetChild(i) ; this .transform.DetachChildren();Transform tf = screen.transform.GetChild(0 ); Destroy(tf.gameObject);
3 GameObject 属性
this .gameObject.activeInHierarchy;this .gameObject.activeSelf;
方法
this .gameObject.SetActive(bool );this .gameObject.AddComponent<class >();GameObject.Find("name" ); GameObject.FindGameObjectsWithTag( "tag" ); GameObject.FindWithTag( "tag" );
案例
GameObject lightGo = new GameObject("light" ); Light light = lightGo.AddComponent<Light>(); private Transform pointLight;pointLight = this .transform.GetChild(0 ); pointLight.gameObject.SetActive(false );
4 Object 属性
方法
Destroy(obj,delay); DontDestroyOnLoad(obj); FindObjectOfType<class >(); FindObjectsOfType<class >();
5 Time 属性
Time.time; Time.deltaTime; Time.fixedDeltaTime; this .transform.Rotate(0 ,1 *Time.deltaTime,0 );Time.timeScale; Time.unscaledDeltaTime; Time.realtimeSinceStartup;
方法
案例
void TimeOne (){ float time = Time.time; if (time > this .nextTime && second > 0 ) { this .second--; this .text.text = string .Format("{0:d2}:{1:d2}" , this .second / 60 , this .second % 60 ); this .nextTime++; if (second < 10 ) { this .text.color = Color.red; } } } void TimeTwo (){ this .countTime += Time.deltaTime; if ( countTime >= 1 && second > 0 ) { this .second--; this .text.text = string .Format("{0:d2}:{1:d2}" , this .second / 60 , this .second % 60 ); if (second < 10 ) { this .text.color = Color.red; } countTime -= 1 ; } } InvokeRepeating("TimeThree" , 1 , 1 ); void TimeThree (){ if (second > 0 ) { this .second--; this .text.text = string .Format("{0:d2}:{1:d2}" , this .second / 60 , this .second % 60 ); if (second < 10 ) { this .text.color = Color.red; } } else { CancelInvoke("TimeThree" ); } }
属性
方法
bool res = Input.GetMouseButton(0 );bool res = Input.GetMouseButtonDown(0 );bool res = Input.GetMouseButtonUP(0 );bool res = Input.GetKey(KeyCode.A);bool res = Input.GetKeyDown(KeyCode.A);bool res = Input.GetKeyUp(KeyCode.A);bool res = Input.GetButton("name" );bool res = Input.GetButtonDown("name" );bool res = Input.GetButtonUp("name" );float value = Input.GetAxis("name" );float value = Input.GetAxisRaw("name" );
案例
if (Input.GetKey(KeyCode.C)&&Input.GetKeyDown(KeyCode.D));
7 其他函数 唤醒
void Invoke ("MethodName" , "time" ) ; InvokeRepeating("MethodName" , start_time , Repeat_rate ); CancelInvoke("MethodName" );
8 常用API组成功能 MeshRenderer meshRenderer = this .GetComponent<MeshRenderer>(); this .material = meshRenderer.materials[0 ];this .material.color = Color.yellow;this .transform.Translate(0 , 0 , moveSpeed * Time.deltaTime);this .transform.Translate(0 , 0 , 0 ,Space.World);this .transform.Translate(0 , 0 , 0 ,Space.Self);void Update (){ if (anim.a){}; if (anim.b){}; }
四、动画 1 UI
using UnityEngine.UI;
2 Animation
脚本控制 Animation 时要把组件中的 Play Automatically 关闭。
属性
方法
bool isPlay = anim.isPlaying;bool isPlay = anim.isPlaying("name" );anim.Play("name" ); anim.PlayQueued("name" ); anim["name" ].speed = num; anim["name" ].length; anim["name" ].time; anim.animation.CrossFade("name" ); anim.CrossFadeQueued("name" ); anim.stop();
案例
private void OnMouseDown (){ if (!doorState) { door[animName].speed = 1 ; } else { door[animName].speed = -1 ; if (door.isPlaying == false ) door[animName].time = door[animName].length; } door.Play(animName); doorState = !doorState;
异常
Legacy异常
事件没有绑定方法
1. 动画——Inspector的Normal改Debug;2. 勾选Legacy;
3 Animator 属性
private Animator animator = GetComponent<Animator>();
方法
animator.GetCurrentAnimatorStateInfo(idx); animator.GetCurrentAnimatorStateInfo(idx).IsName(name);
案例
animator.GetCurrentAnimatorStateInfo(0 ).IsName("Walk" )
4 导入MMD
插件:Author::Stereoarts Homepage
导入包。
导入pmx文件包,会在路径下自动生成一个.MMD4Mecanim文件,点击agree
配置pmx和vmd文件。
生成了一个可播放物件,该物件右边有一个播放按钮。
若模型显示不全则进入同名文本文件下修改<commentEn></commentEn>
中的内容
5 音频 属性
audio.clip; protected AudioClip[] audioClips;
方法
private audio audioSource = GetComponent<AudioSource>();audio.Play(); audio.PlayOneShot(audio.clip);
案例
private AudioSource audioSource;audioSource = GetComponent<AudioSource>(); audioSource.clip = Resources.Load<AudioClip>("bgm" ); audioSource.loop = true ; audioSource.volume = 0.5f ; audioSource.Play(); audioSource.Stop();
五、三维数学 1 Mathf 属性
Mathf.PI; radian = angle * Mathf.Deg2Rad; angle = radian * Mathf.Rad2Deg;
方法
Mathf.Abs(num); Mathf.Pow(num,pow); Mathf.Sqrt(num); Mathf.Sin/Cos/Tan(float radian); Mathf.Asin/Acos/Atan(float radian); point = Mathf.Lerp(start,end,step);
案例
radian = angle * Mathf.PI / 180 ; radian = angle * Mathf.Deg2Rad; angle = radian * 180 / Mathf.PI; angle = radian * Mathf.Rad2Deg;
2 Vector 属性
Vector3.back = new Vector3(0 ,0 ,-1 ); forward,back,up,down,left,right,one,zero; Vector3.magnitude Vector3.normalized Vector3.sqrMagnitude
方法
angle = Vector3.Angle(from ,to); clampedVector = Vector3.ClampMagnitude(inputVector, maxMagnitude); vector = Vector3.Cross(a,b); vector = Vecotr3.Dot(a,b); vector = Vecotr3.Distance(a,b); vector3.OrthoNormalize(ref basisA,ref returnB,ref returnC); vector = Vector3.ProjectOnPlane(A,plane); vector = Vector3.Reflect(inDirection,inNormal); vector = Vector3.MoveTowards(src,dest,speed); vector = Vector3.Lerp(src,dest,speed); vector = Vector3.LerpUnclamped(src,dest,speed);
案例
public AnimationCurve curve; private float x; public float duration; if (GUILayout.RepeatButton("LerpUnclamped" )){ x += Time.deltaTime / duration; this .transform.position = Vector3.LerpUnclamped(Vector3.zero,targetPos,curve.Evaluate(x)); }
3 Quaternion 属性
Quaternion qt = this .transform.rotation; Vector3 euler = qt.qulerAngles; Quaternion.identity;
方法
rotation = Quaternion.Euler(x,y,z); float angle = Quaternion.Angle(rotationA, rotationB);rotation = Quaternion.AngleAxis(angle, axis); rotation = Quaternion.LookRotation(position); Quaternion newRotation = Quaternion.RotateTowards(currentRotation, targetRotation, maxDegreesDelta); rotation = Quaternion.FromToRotation(A,B);
案例
if (GUILayout.RepeatButton("rotation" )){ Quaternion dir = Quaternion.LookRotation(tf.position - this .transform.position); this .transform.rotation = Quaternion.Lerp(this .transform.position,dir,0.1f ); }
4 向量 属性
二维向量的模长用公式自己算。
Vector3.zero; float m = vector.magnitude;float m = vector.sqrMagnitude;Vector3 n = pos.normalized;
运算
向量点乘:,反余弦角度在[0,180]之间。
向量叉乘:,Unity中方向左手规则。反余弦角度在[0,90]之间。
Vector3 vector = vector_x - vector_y; float dot = Vector3.Dot(va,vb);Vector vector = Vector3.Cross(a,b);
方法
using UnityEngine;Vector3.Distance(a,b); vector.Normalize();
案例
float m = Mathf.Sqrt(Mathf.Pow(pos.x,2 )+Mathf.Pow(pos.y,2 )+Mathf.Pow(pos.z,2 ));float m = pos.magnitude; float m = Vector3.Distance(Vector3.zero,pos);Vector3 n = pos / pos.magnitude; Vector3 n = pos.normalized; point.Translate(Direction.normalized);
5 旋转 概念
欧拉角:用三个角度来保存方位。(xz轴转沿自身旋转,y轴转沿世界旋转)
欧拉角的数据类型是Vector3,欧拉角没有大小和方向,仅因为有xyz所以用Vector3存储。
欧拉角优点:好使方便。
欧拉角弊端:
方位表达不唯一([250,0,0]和[290,180,180]是同一个角度)。所以为了保证唯一,用代码操作角度时,x限定在[-90,90],yz限定[0,360]。
万向节死锁。物体沿X轴旋转90度后,自身Z轴会与世界Y轴重合,此时再沿Y或Z旋转时将失去一个自由度。在次情况下,规定沿Y轴完成绕竖直轴的全部旋转,此时Z轴旋转为0。
四元数:3D中表示旋转,旋转都沿自身,分量如下(值域都是[-1,1]):
四元数优点:没有死锁。
四元数弊端:难用,不建议单独改某个值,存在不合法的四元数值。
属性
this .transform.up;this .transform.right;this .transform.forward;Vector3 eulerAngle = this .transform.eulerAngles; Quaternion qt = this .transform.rotation;
运算
Quaternion.Euler(0 ,50 ,0 ) = Quaternion.Euler(0 ,30 ,0 ) * Quaternion.Euler(0 ,20 ,0 );
方法
this .transform.rotation = Quaternion.Euler(x,y,z);
案例
Vector3 axis = Vector3.up; float rad = 50 * Mathf.Deg2Rad;Quaternion qt = new Quaternion(); qt.x = Mathf.Sin(rad / 2 ) * axis.x; qt.y = Mathf.Sin(rad / 2 ) * axis.y; qt.z = Mathf.Sin(rad / 2 ) * axis.z; qt.w = Mathf.Cos(rad / 2 ); this .transform.rotation = qt;Vector3 rect = this .transform.position + Quaternion.Euler(0 ,30 ,0 ) * this .transform.rotation * new Vector3(0 ,0 ,10 ); rect = this .transform.rotation * new Vector3(0 ,0 ,10 ); rect = Quaternion.Euler(0 ,30 ,0 ) * rect; rect = this .transform.position + rect;
6 碰撞 概念
碰撞条件:两者都有碰撞组件,运动的物体有刚体组件。
速度不能过快,不然检测不到。一般100以下。
属性
ContactPoint cp = other.contacts[0 ]; cp.point; cp.normal;
方法
void OnCollisionEnter (Collision other ) ;void OnCollisionStay (Collision other ) ;void OnCollisionExit (Collision other ) ;
案例
private void OnCollisionEnter (Collision other ){ other.collider.GetComponent<>(); ContactPoint cp = other.contacts[0 ]; }
7 触发 概念
带有碰撞器组件,且Is Trigger被勾选的物体。
现象:无碰撞效果。
触发条件:
两者具有碰撞组件。
其中之一带有刚体组件。
其中之一勾选Is Trigger。
速度不能过快,不然检测不到。一般100以下。
方法
void OnTriggerEnter (Collider other ) ;void OnTriggerStay (Collider other ) ;void OnTriggerExit (Collider other ) ;
案例
private void OnTriggerEnter (Collision other ){ other.GetComponent<>(); }
8 坐标系转化 属性
方法
vector = transform.TransformPoint(position); vector = transform.TransformDirection(position); vector = transform.TransformVector(position); vector = transform.InverseTransformPoint(position); vector = transform.InverseTransformDirection(position); vector = transform.InverseTransformVector(position); vector = Camera.main.WorldToScreenPoint(position); vector = Camera.main.ScreenToWorldPoint(position); vector = Camera.main.WorldToViewportPoint(position); vector = Camera.main.ViewportToWorldPoint(position);
案例
Vector3 screenPosition = new Vector3(0.3f * Screen.width, 0.3f * Screen.height, 0f ); Vector3 worldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
六、 UGUI
UI的进化:OnGUI——NGUI——UGUI
UI操作时,设置为2D,并且按 T(左上角第五个操作) ,便于进行UI物体的操作。
左键操作物体,右键操作画布。
1 Canvas
UGUI中的所有元素必须在Canvas之下。
Render Mode(画布模式):
Screen Space - Overlay(屏幕空间 - 覆盖):
Canvas以屏幕为坐标系,覆盖在其他所有对象之上。
不会受到场景中物体的遮挡,始终会显示在最前面。
适用于出现在游戏界面上方的固定UI元素。
Screen Space - Camera(屏幕空间 - 相机):
Canvas以相机为坐标系,并且渲染在相机的近裁剪面前。
可以通过指定渲染的目标摄像机来控制可视范围。
适用于与3D场景进行交互或需要基于相机进行渲染的UI元素。
World Space(世界空间):
Canvas以世界坐标系进行绘制,可以放置在场景中的任意位置。
可以根据世界坐标位置进行缩放、旋转等变换操作。
注:在World Space模式下,通常需要借助Event System来处理交互事件。
Sort Order:
同一画布下元素,后面的元素盖住前面的元素。
不同画布下,Sort Order大的盖住小的。
Canvas Scaler(做任何UI前必做,否则后续界面会乱! ):
技巧:
3D的UI:让文体或图片贴在3D物体上。首先设置相机为World Space模式,然后该Scale为(0.01,0.01,0.01)。然后改变Image或Text的物件的位置,让其和物体重合。之后移动相机就会发现它们一直是重合的。
2 简单组件
通用属性:
Panel:
一个界面就是一个Panel。切换界面是在同一个Canvas下切换不同Panel。
TextMeshPro:
安装:Window——TextMeshPro——Import TMP Essential Resources
Rich Text:可以写部分html标签改变字的样式。
字体格式:.ttf——右键——Cteate——TextMeshPro——Font Asset
Button:
在Button绑子物体Text完成一个简单按钮制作。
Interactable:是否可交互。
Transition:不同情况下按钮的变化。
Navigation:一般没用,设置None可以解决点击后颜色显示不正常的BUG。
Toggle:
复选框。
Toggle——Background:背景框样式。
Toggle——Background——Checkmark:选中样式。
Toggle——Label:文本样式。
Is On:是否选中。
Slider:
滑动条。
做血条可以点Interactable不允许交互。
Scrollbar:
Dropdown:
Image
格式:图片——Texture Type——Sprite。
Image Type:图片类型
Filled:类似技能冷却。(Fill Amount:转圈)
Set Native Size:根据图片大小设置大小。
优化原理:界面中默认一张图片一个Draw Calls,同一张图多次显示仍是一个Draw Calls。所以可以把多个小图放到一个大图中,这样就是一个Draw Calls。
Sprite打包步骤如下:
Window——Package Manager——Packages:Unity Registry——2D Sprite——Install
Edit——Project Settings——Editor——Sprite Packer——Mode设置为Enabled For Builds 或 Always Enabled(建议第一个。第一个是仅项目打包时检查图片变化,第二个是每次都会检查图片变化。)
Create——2D——Sprite altas。
将图片添加到图集中。
Sprite切割步骤如下(图集不可切割):
Sprite Mode——Multiple
Sprite Editor
左上角第二个箭头——Type(切割模式)——切割后改名(若名字错误不可在文件中直接改,而是按此步骤重新在编辑器中改)
SpriteAtlas sprites = Resources.Load<SpriteAtlas>("path" ); foreach (Sprite sprite in sprites.GetPackables()){}static ResourcesManager () { spriteDict = new Dictionary<int , Sprite>(); Sprite[] sprites = LoadSpritesFromAtlas("People" ); foreach (Sprite sprite in sprites) { sprite.name = sprite.name.Replace("(Clone)" , "" ); int id = int .Parse(sprite.name); spriteDict.Add(id, sprite); } } private static Sprite[] LoadSpritesFromAtlas (string atlasName ){ Sprite[] sprites = null ; SpriteAtlas spriteAtlas = Resources.Load<SpriteAtlas>(atlasName); if (spriteAtlas != null ) { sprites = new Sprite[spriteAtlas.spriteCount]; spriteAtlas.GetSprites(sprites); } return sprites; }
概念
Pos:控件轴心点相对于自身锚点的位置。
Pivot:控件轴心点位置。
锚点:合并会进行位置自适应,分开会进行大小自适应。(点击middle center图像可以选择锚点位置)
属性
this .transform.position;this .transform.localPosition;RectTransform rtf = GetComponent<RectTransform>(); RectTransform rtf = this .transform as RectTransform; rtf.position;rtf.localPosition; vector3 rtf.anchoredPosition3D; vector2 rtf.anchorMin; rtf.pivot; rtf.rect.width; rtf.rect.height; vector2 rtf.sizeDelta; RectTransformUtility
方法
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 250 );
4 事件
绑定事件:
编辑器绑定:
把脚本拖到物体上
把物体拖到按钮事件中
找到函数并添加即可(函数可以有参数string)
AddListener
实现接口
自定义框架
管理事件:
Event System(Script):管理事件
Standalone Input Module(Script):分发和检测事件(作用于PC和移动)
Graphic Raycaster(Script):检测事件
接口事件
使用:
在类后面继承对应的事件类
Ctrl + .后接回车,会自动生成一个函数
IPointerEnterHandler; IPointerExitHandler; IPointerDownHandler; IPointerUPHandler; IPointerClickHandler; IBeginDragHandler; IDragHandler; IEndDragHandler; IDropHandler; IUpdateSelectedHandler; ISelectHandler; IDeselectHandler; IScrollHandler; IMoveHandler; ISubmitHandler; ICancelHandler;
案例
Button btn = this .transform.Find("Button" ).GetComponent<Button>(); btn.onClick.AddListener(Func); public void OnPointerClick (PointerEventData eventData ) { if (eventData.clickCount == 2 ) { } } public void OnDrag (PointerEventData eventData ) { this .transform.position = eventData.position; RectTransform parentRTF = this .transform.parent as RectTransform; Vector2 worldPos; RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRTF, eventData.position, eventData.pressEventCamera, out worldPos); this .transform.localPosition = worldPos; } public class EventDemo : MonoBehaviour , IPointerDownHandler , IDragHandler { private RectTransform parentRectTransform; private Vector2 offset; void Start () { parentRectTransform = transform.parent as RectTransform; } public void OnPointerDown (PointerEventData eventData ) { offset = (Vector2)transform.position - eventData.position; } public void OnDrag (PointerEventData eventData ) { Vector2 localPos; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRectTransform, eventData.position, eventData.pressEventCamera, out localPos)) { transform.localPosition = localPos + offset; } } }
5 iTween 概念
下载:official::iTween下载
导入:Window——Package Manager——Packages:My Assets——Download——Import
目的是轻松实现各种动画。
方法
iTween.MoveTo(); iTw2een.ColorTo(); iTween.FadeTo(); iTween.CameraFadeAdd(); iTween.CameraFadeTo(); iTween.LookTo(); iTween.RotateTo(); iTween.ScaleTo(); iTween.PunchPosition(); iTween.PunchRotation(); iTween.PunchScale(); iTween.ShakePosition(); iTween.ShakeRotation(); iTween.ShakeScale(); iTween.Hash();
案例
public class ITweenDemo : MonoBehaviour { public Transform imgTF, btnTF; public float moveSpeed = 100 ; public void DoMovement () { iTween.MoveTo(imgTF.gameObject, btnTF.position, 2 ); } } public iTween.EaseType type;public void DoMovement (){ iTween.MoveTo(imgTF.gameObject, iTween.Hash( "position" ,btnTF.position, "speed" ,moveSpeed "easetype" ,type )); } public void CreateEffect (){ iTween.ScaleFrom(gameObject, Vector3.zero, 0.3f ); } iTween.MoveFrom(imgTF.gameObject,iTween.Hash( "position" ,btnTF.position, "speed" ,moveSpeed, "easetype" ,type, "oncomplete" ,"Func" , "oncompletetarget" ,gameObject )); private void Func (){ print("over!" ); }
七、存储 1 PlayerPrefs 概念
持久的在本地进行存储。
方法
PlayerPrefs.SetFloat(key,value ); PlayerPrefs.SetInt(key,value ); PlayerPrefs.SetString(key,value ); PlayerPrefs.GetFloat(key,default ); PlayerPrefs.GetInt(key,default ); PlayerPrefs.GetString(key,default ); PlayerPrefs.DeleteAll(); PlayerPrefs.DeleteKey(key); PlayerPrefs.HasKey(key);
案例
2 SceneManager 概念
场景切换。
方法
SceneManager.LoadScene("SceneName" );
3 外部资源加载 Resources
Sprite Resources.Load<Sprite>("path" ); Sprite[] Resources.LoadAll<Sprite>("path" ); SpriteAtlas sprites = Resources.Load<SpriteAtlas>("path" ); foreach (Sprite sprite in sprites.GetPackables()){}
AssetDatabase
string assetPath = "Assets/Folder/FileName.extension" ;GameObject asset = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
八、Component 1 Rigidbody 2D 概念
2D刚体
属性
private Rigidbody2D rb = GetComponent<Rigidbody2D>();rb.velocity = new Vector2(x,y); ForceMode2D.Force; ForceMode2D.Impulse; ForceMode2D.VelocityChange; ForceMode2D.Acceleration;
方法
rb.AddForce(Vector2.up, ForceMode2D.Impulse);
案例
rb.AddForce(Vector2.up * jump * jumpSpeed, ForceMode2D.Impulse);
2 NavMeshAgent 概念
2D刚体
属性
private NavMeshAgent agent = GetComponent<NavMeshAgent>();agent.isStopped = true ;
方法
3 Line Renderer 概念
线渲染,常用于射线。
Materials:材质。
Positions:
Paramters
案例
line = GetComponent<LineRenderer>(); if (true ){ line.enabled = true ; line.SetPosition(0 ,startPosition); line.SetPosition(1 ,endPosition); } else { line.enabled = false ; }
九、其他 1 NGUI
$95购买:official::NGUI
绑定事件在物体中绑定。
public class ButtonClickHander : MonoBehaviour { private void Start () { for (int i = 0 ;i < transform.childCount; i++) { transform.GetChild(i).GetComponent<UIButton>().onClick.Add(new EventDelegate(OnButtonClick)); } } public void OnButtonClick () { print("Button name is" + UIButton.current.name); } }
2 协程
类似python迭代器。
多个协程可以同时运行,它们会根据各自的启动顺序来更新。
协程可以嵌套。
多个脚本访问一个协程,协程可以定义为静态协程。
协程是单线程。
协程的方法不能带ref和out型参数。
方法
private IEnumerator Func (){ yield return n; yield return n; } yield return n;yield return new WaitForSeconds (time ) ; yield return new WaitForSecondsRealtime (time ) ; yield return new WaitForFixedUpdate () ;yield return new WaitForEndOfFrame () ;WWW www = new WWW(url); yield return www;StartCoroutine(func(para)); StopCoroutine(func(para)); StopAllCoroutines();
案例
private void Start (){ StartCoroutine(CountDown(60 )); } private IEnumerator CountDown (int timeCount ){ do { print(timeCount); yield return new WaitForSeconds (1 ) ; timeCount -= 1 ; } while (timeCount > 0 ); print("Game Over!" ); } private void OnGUI (){ if (GUILayout.Button("Start" )) StartCoroutine(MoveToPath()); } private IEnumerator MoveToPath (){ foreach (Transform point in points) { yield return (StartCoroutine(MoveToTarget point.position ) ; yield return new WaitForSeconds (2 ) ; } } private IEnumerator MoveToTarget (Vector3 target ){ while (transform.position != target) { transform.position = Vector3.MoveToWards(transform.position,target,Time.deltaTime * speed); yield return new WaitForFixedUpdate () ; } }
3 射线 概念
射线。
属性
private Ray ray;private RaycastHit hit;ray.origin; ray.direction; hit.point; hit.collider; hit.distance;
方法
ray = Camera.main.ScreenPointToRay(Input.mousePosition); public LayerMask layer;Physics.Raycast(ray,out hit,distance,layer.value ); Physics.Raycast(origin,direction,out hit,distance,layer.value );
案例
public Camera camera;ray = camera.ScreenPointToRay(Input.mousePosition);
十、状态机
如下为Player框架
1 状态控制脚本 1.1 Player
1.2 PlayerState
1.3 PlayerStateMachine
2 普通状态 2.1 PlayerIdleState
2.2 PlayerMoveState
3 超级状态
一个超级状态可以有其他不同的普通状态存在。例如:接地状态和空中状态。接地可以是闲置和移动。因此接地是一个超级状态。
3.1 PlayerGroundState
3.2 PlayerAirState