【Unity】一些个人心得
-
UI锚点相关知识
锚点可以理解为图片的四个角到其对应锚点的距离始终不变。图片右上对应锚点右上,等。
锚点会显示各锚点相对于屏幕的占比。这意味着当改变屏幕分辨率时,锚点也会按照对应百分比改变。如一个50%,30%,20%的锚点,当拉长100像素时,从左到右的两个锚点会向右移动50像素和80(50+30)像素。可以利用这个预想分辨率改变后的情况。UI(或某物体)看向某物体
public Transform target; public Vector3 axisY = Vector3.up; void Update() { Vector3 dir = target.position - transform.position; //指向目标物体的向量 Quaternion ang = Quaternion.LookRotation(dir, axisY); //让物体看向上述向量方向。如果省略axisY,那么值默认为Vector3.up //具体实现方法是首先令物体z轴朝向dir,然后根据dir和axisY做乘法求出向右垂直于dir和axisY两向量形成的平面的向量,作为物体的x轴,然后用z轴和x轴再来一次求出y轴。 transform.rotation = ang; }
类明日方舟点击拖拽上阵方式
使用
public class UIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
然后再分别实现
public void OnBeginDrag(PointerEventData eventData) OnDrag OnEndDrag
就可以完成一套拖拽流程了。
之后给塔基座添加射线碰撞检测if (Input.GetMouseButtonDown(0)) { if (EventSystem.current.IsPointerOverGameObject() == false) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; bool isCollider = Physics.Raycast(ray, out hit, 1000, LayerMask.GetMask("Towerbase")); if (isCollider) { //hit.collider.GetComponent<xxx>(); } } }
再加入鼠标移上去变色效果和建造功能
void OnMouseOver() { if (Level_GlobalVariable.CAN_BUILD == true) { myRenderer.material.color = Color.red; if(Input.GetMouseButtonUp(0)) { if(isBuilded == false) { Instantiate(tempTower,transform.GetChild(0).transform.position,Quaternion.identity,transform); isBuilded = true; } } } else { myRenderer.material.color = Color.white; } } void OnMouseExit() { myRenderer.material.color = Color.white; }
上面的全局变量是只在当前场景使用的
-
-
同比放大移动速度除了可以用Vector2(xSpeed * param,ySpeed * param)以外,还可以用Vector2(xSpeed, ySpeed) * param;另外为了避免不同电脑的帧数差别导致的巨力,可以使用Vector2(xSpeed, ySpeed) * param * Time.deltaTime
-
用velocity做跳跃移动
跳跃的时候向量速度=向量速度.x , 跳跃速度
移动的时候向量速度 = 移动速度,向量速度.y -
class默认不会被序列化,想要class显示的话需要using System.Collections.Generic;里面的 [Serializable],相应的,如果你的public了一个class,但这个class没有在inspector里面显示,那么就是因为你这个class没有被序列化,在对应class前面加[Serializable]就可以了
-
使用[SerializeField]强制将private的属性显示在inspector里
-
使用[Range(1,3)]控制某个值在inspector里面拖拽可以更改的范围(代码里不限制)
-
如果在使用动画的情况出现了某些操作上的bug,检查一下动画本身是否自带动作,导致动画动作覆盖了你的操作
-
移动除了使用路点移动以外,还可以使用贝塞尔曲线移动,以下是对贝塞尔曲线的解释和代码
//贝塞尔曲线解释: //定一个0到1的比例t,n个点组成n-1条线段,然后求每段线段在比例t下的点的位置,如果求取后点的数目大于1,那么继续将它们按顺序组成线段,求取这些线段在比例t下的点位置 //然后t从0到1移动,就组成了曲线 //静态贝塞尔类的定义,用于计算 public static class Bezier { //定义GetPoint方法 //作用是获取一系列点依据贝塞尔曲线计算规则后,位于比例t的点 public static Vector3 GetPoint(Vector3[] points, float t) { //建立一个新数组,复制传入的数组后,使用Unity自带的插值算法,从第一个点开始,依次计算两点之间的插值点 //计算一轮过后,总共的点的数目就减少了1,重复此过程,直到只剩一个点,该点就是所有原始点连成的贝塞尔曲线在比例t下的点的位置 //然后返回这个点就行了 Vector3[] newPoints; int pointsNumber = points.Length; newPoints = new Vector3[pointsNumber]; //要用array.copy函数,否则的话就传了地址,会出bug Array.Copy(points, newPoints, pointsNumber); while (pointsNumber > 1) { for (int i = 0; i < pointsNumber - 1; i++) { newPoints[i] = Vector3.Lerp(newPoints[i], newPoints[i + 1], t); } pointsNumber -= 1; } return newPoints[0]; } }
- AnimationCurve类可以创建曲线,用途多多,以下是清除所有曲线点的示例:
(正序的做法会删除一半的点,我还不清楚为什么)
for(int i = animationCurve.keys.Length-1; i>-1;i--) { animationCurve.RemoveKey(i); } //然后这里是将贝塞尔曲线分为100段,算出每段的平均速度并将其添加到曲线上的代码,GetPoint方法的作用是传入一个三维向量数组和比例t,返回使用这个数组计算的贝塞尔曲线在比例t下的位置 for (int i = 0; i < 100;i++) { t = (float)i / 100f; nextT = (float)(i + 1) / 100f; length = (GetPoint(points, t) - GetPoint(points, nextT)).magnitude; deltaTime = length / speed; deltaSpeed = 0.01f / deltaTime ; animationCurve.AddKey((float)i/100f, deltaSpeed); if(i == 99) { animationCurve.AddKey(1, deltaSpeed); } }
- 在挂载了对应脚本的物体的inspector下面额外显示按钮
[CustomEditor(typeof(MyWaveController))] public class thisEditor : Editor { public override void OnInspectorGUI() { DrawDefaultInspector(); if (GUILayout.Button("按钮名称")) { //把要执行的内容写在这里 } } }
-
-
@GShion 使物体朝着前方移动一般是使用各种.forward .up什么的,然后向这个方向更改位置或者速度。
-
没发生碰撞检测的常见原因:
rigidbody没得
onCollisionEnter(2D)写错了动画移动错误的一些原因
应用了动画根运动