Design Hub

    • 注册
    • 登录
    • 搜索
    • 版块
    • 最新

    【Unity】一些个人心得

    游戏开发
    1
    4
    699
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • GShion
      GShion 管理员 最后由 GShion 编辑

      UI锚点相关知识

      3335f7e8-7bda-41a0-ad7c-1d8f4e24a802-image.png

      锚点可以理解为图片的四个角到其对应锚点的距离始终不变。图片右上对应锚点右上,等。
      锚点会显示各锚点相对于屏幕的占比。这意味着当改变屏幕分辨率时,锚点也会按照对应百分比改变。如一个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;
          }
      

      上面的全局变量是只在当前场景使用的

      我就是挖坑不填林诗音!

      GShion 1 条回复 最后回复 回复 引用
      • GShion
        GShion 管理员 @GShion 最后由 编辑

        • 同比放大移动速度除了可以用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 1 条回复 最后回复 回复 引用
        • GShion
          GShion 管理员 @GShion 最后由 编辑

          @GShion 使物体朝着前方移动一般是使用各种.forward .up什么的,然后向这个方向更改位置或者速度。

          我就是挖坑不填林诗音!

          1 条回复 最后回复 回复 引用
          • GShion
            GShion 管理员 最后由 编辑

            没发生碰撞检测的常见原因:
            rigidbody没得
            onCollisionEnter(2D)写错了

            动画移动错误的一些原因
            应用了动画根运动

            我就是挖坑不填林诗音!

            1 条回复 最后回复 回复 引用
            • 1 / 1
            • First post
              Last post
            版权所有 ©2023 Design Hub 保留所有权利
            鄂ICP备2021004164号-2