Unity基础

作者: akiunique | 来源:发表于2016-06-21 15:03 被阅读495次

    Unity基础开发--游戏蛮牛

    1. 不认识的词

    respawn [ˌriːˈspɔːn] vt. 复位vi. 重生
    magnitude 英 ['mægnɪtjuːd] 美 ['mæɡnɪtud] n. 大小;量级;[地震] 震级;重要;光度
    albedo 英 [æl'biːdəʊ] 美 [æl'bido]n. (行星等的)反射率;星体反照率
    emission n. [环境] 排放;[环境] 排放物,辐射;发行
    quaternion 英 [kwə'tɜːnɪən] 美 [kwə'tɝnɪən]n. 四元数;四个一组;四人一组
    interpolate 英 [ɪn'tɜːpəleɪt] 美 [ɪn'tɝpəlet] vt. 篡改;插入新语句vi. 插入;篡改
    torque 英 [tɔːk] 美 [tɔrk] n. 转矩,[力] 扭矩;项圈,金属领圈v. (向轴、螺栓、圆轮等)施以扭动力;(使)沿轴转动;使(绕轴等)扭转;施加转矩
    polygon 英 ['pɒlɪg(ə)n] 美 ['pɑlɪɡɑn] n. 多边形;多角形物体

    2. GameObject

    • SetActive()
    gameObject.SetActive (false);   //设置为不激活,设置后不可见
    
    • GetComponent<T>()
    CubeController c =  gameObject.GetComponent<CubeController>(); 
                                                    //获取组件 泛型类型为组件名称类
    
    • Destroy ()
    if ( Input.GetKeyDown (KeyCode.S) ) {
         GameObject.Destroy (gameObject,2f);   }   } //两秒后销毁gameObject
    
    • GameObject 实例方法:
      Name
      Tag
      ActiviSelf
      SetActive()
      GetComponent<T>()
      AddComponent<T>()

      类方法:
      Destory()
      FindGameObjectWithTag()
      Find()

    3. Vector3

    • 三维向量,是一个类,表示向量。
    • Vector3.up; x = 0,y = 1,z= 0。世界坐标系中y轴正方向上的单位向量。
      还有:up、down、right、left、forward、back。
    • Vector3.zero; 世界坐标系中得原点
    • 获取v的长度
    float l = v.magnitude;
    
    • 获取v的单位向量

    · 方法一

     v.Normalize(); //将v的长度变为1 方向不变 无返回值
    

    · 方法二

    Vector3 vn = v.normalized(); //返回v方向上的单位向量,v本身不发现变化
    
    • 求两个向量的夹角
    Vector3 v1 = new Vector3(1.4f,6f,7.2f);
    Vector3 v2 = new Vector3(2f,6.5f,12.3f);
    float angle = Vector3.Angle(v1,v2); //返回一个角度 只有正数 不带方向
    
    • 获取两个点距离
    Vector3 pos1 = new Vector3(4f,2f,11f);
    Vector3 pos2 = new Vector3(2f,13.6f,8f);
    Vector3.Distance (pos1,pos2);
    
    1. 向量点乘
    float dd = Vector3.Dot(v1,v2);
    
    • 向量叉乘
    Vector3 vc = Vector3.Cross(v1,v2);
    

    4. Transform

    • 每个GameObject 必备组件。

    1 控制游戏对象的位置,旋转,缩放;

    • 对于控制游戏对象的位置旋转缩放的position属性
    //位置
    Vector3 pos1 = transform.position; //以世界坐标系来显示位置
    Vector3 pos2 =transform.localPosition; //局部坐标系显示位置
    transform.position = Vector3.zero'
    //缩放
    Vector3 sc = transform.localScale; 
    transform.localScale = new Vector3(1f,2f,1f); //长宽高变为1 2 1
    

    注意:当一个对象没有父对象时,transform中的坐标以世界坐标系来显示;当有父对象时,按局部坐标系显示。

    • 产生位移的方法
    void Update () {
        //变换当前游戏对象
        transform.Translate (new Vector3(0,1,0)); //新的位置 = 现在的位置 + 参数
        //旋转当前游戏对象
        transform.Rotate(Vector3.up , 10f); //以y轴正方向为轴旋转10度
        //属性 —— 欧拉角
        transform.eulerAngles = new Vector3(0f,45f,0f); //转到这个位置状态,执行一次
    }
    

    2 管理游戏对象父子之间的关系。

      transform.parent; //获取或重新指定当前游戏对象的父对象的transform组件,get + set
      transform.root; //获取当前游戏对象的根对象,只有get
      transform.Find("Cube"); //通过名字查找子对象的transform组件并返回
      transform.FindChild("Cube");//重名时默认返回第一个自对象
    

    5. Time 和Mathf类

    • Time类封装了常用的时间控制方法
    • Mathf类封装了常用的数学方法

    Time类:

    float t =Time.time; // 游戏运行开始到当前帧运行的总时长,以秒记
    float d =Time.deltaTime; //时间增量,从上一帧开始到当前帧结束之间的时间间隔
                             //FPS一般为60帧/s,即deltaTime为0.016秒左右,但不完全相同
    
    //有些运动需按秒记时使用deltatime
    transform.Rotate (Vector3.up,Time.deltaTime*30f); //让当前游戏对象每秒准确的旋转30度
    transform.Translate(new Vector3(1,0,0)*Time.deltaTime); //每秒沿x轴方向移动1
    
    
    //时间缩放的尺度,默认值为1,2表示2倍速,0表示时间停止游戏暂停
    float ts = Time.timeScale; //物理与动画效果会同步计算
    

    Mathf类:

    int i = Mathf.Abs (-12); //int/float,求绝对值
    int m = Mathf.Max(2,4,1,9,3); //求最大最小值
    float s = Mathf.Sin(30f); //求三角函数
    Mathf.PI; //π
    int sq = Mathf.Sqrt (4); //求平方根
    

    6. 预设体prefab

    能够使对象和资源重复使用,相同的游戏对象可使用同一预设体来创建,对预设体进行修改后所有游戏对象都会相应改变。

    public class Test : MonoBehaviour {
        //将预设体设为公共字段,并在unity中拖入预设体,作为GameObject的一个对象
        public GameObject playerPrefab;
    
        void Update () {
            //每当按下P键就会在场景中创建一个Player游戏对象
            if ( Input.GetKeyDown (KeyCode.P) ) {
                     //动态创建游戏对象,位置为预设体本身的位置
                      Vector3 position = new Vector3();
    
                     //使用random.range()方法产生随机数
                      position.y = 0.5f;
                      position.x = Random.Range (-5f,5f);
                      position.z = Random.Range (-5f,5f);
                      float angle = Random.Range (0f, 360f);
    
                     //Instantiate(playerPrefab);
                     //参数:预设体,游戏对象初始位置,游戏对象初始角度
                     Instantiate (playerPrefab,position, 
                                      Quaternion.AngleAxis(angle,Vector3.up) ); 
                     //Quaternion.identity表示旋转值为0
    
                     //Instantiate 返回Object类型 需使用as关键字将其转换为GameObject类型
                      GameObject P = Instantiate (playerPrefab, position,
                                Quaternion.AngleAxis(angle,Vector3.up) ) as GameObject;
                             }
               }
    }
    

    7. 鼠标事件

    • OnMouseDown()
      OnMouseDrag()
      OnMouseUp()
      OnMouseUpAsButton()
      OnMouseEnter()
      OnMouseOver()
      OnMouseExit()
    //鼠标点击
    //1. 当鼠标点击时调用 点下必须在对象内部
    void OnMouseDown() {
         print ("按下鼠标"); //只对按上该物体有用,每点击一次执行一次
        //与Input.GetMouseButtonDown()的区别为input点击画面各处都触发 }
    
    //2 当鼠标取消点击时调用
    void OnMouseUp(){
         print ("抬起鼠标");
    }
    
    //3 鼠标在对象内部按下不松
    void OnMouseDrag(){
         print ("按住鼠标");
    }
    
    //鼠标滑动
    //4 鼠标移动到对象内时调用
    void OnMouseEnter(){
         print ("enter鼠标");
    }
    
    //5 鼠标离开对象内时调用
    void OnMouseExit(){
         print ("exit鼠标");
    }
    
    //6 鼠标持续停留在游戏对象上时调用
    void OnMouseOver(){
         print ("停留鼠标");
    }
    
    //7 只有在物体内弹起鼠标才触发,与OnMouseUp()的区别在于Up在外部弹起也会打印, 当然都需要在内部点下
    void OnMouseUpAsButton(){
         print ("像按钮一样弹起鼠标");
    }
    

    8. 刚体 RigidBody

    • 面板
      mass:质量。
      drag:空气阻力,不能表示摩擦力。
      Angular Drag:角阻力,旋转时慢慢停下。
      Use Gravity:是否受到重力影响。
      Is Kinematic:是否有运动学,也可让物体运动,通过施加力使物体运动,与transform的让物体运动的方法两者只能存在一个。勾选时不受物理引擎控制 如重力等。
      interpolate:差值 计算位置的方式。none-interpolate内插值,extrapolate外插值。
      物理引擎按帧计算游戏对象位置 若过程中物体颤抖则采用差值方式推算当前帧位置。
      内插值:通过当前帧的上一帧推算当前帧;
      外插值:预测游戏对象下一帧位置推算当前帧。
      Collision Detection:碰撞检测。
      Discrete 离散。
      continuous 连续。防止高速运动的物体穿透障碍物
      continuous dynami c连续动态 防止两个高速物体碰撞
      Constraints 约束。冻结位移,冻结旋转。
    1. 常用函数
      AddForce() 施加力
      AddExplosionForce() 施加爆炸力
      AddTorque() 施加力矩
      AddForceAtPosition() 在指定位置施加力
    r = GetComponent<RigidBody>();
      if (Input.GetKey (KeyCode.Alpha1)) {
    
          r.AddForce(new Vector3(0f,10f,0f));  //给当前游戏对象添加一个力
          r.AddTorque(new Vector3(0f,10f,0f));  //添加扭矩/力矩
    
          //不在物体重心 而是在指定位置添加力。
          //第二个坐标为施加力的位置,为cube的本地坐标系,一个角
           r.AddForceAtPosition( new Vector3(0f,10f,0f), new Vector3(0.5f,0.5f,0.5f)); 
      }
    
          //在指定位置添加爆炸力参数为:力的大小,爆炸点,爆炸半径 
          //不能持续添加。即不能写在GetKey中而应该在GetKeyDown中
      if (Input.GetKeyDown (KeyCode.Alpha1)) {
           r.AddExplosionForce (2500f, Vector3.zero, 8);
      }
    

    9. Collider

    • 面板
      Is Trigger:是否有触发效果
      Material:物理材质。摩擦力、弹力等。
      Center:Vector3类型
      Size:Vector3类型
      Center和Size是真正碰撞部位的范围和大小。

    • Colider 和 RigidBody
      发生碰撞的条件为:两者都有Colider,至少一方有RigidBody。发生相对运动。

    • Colider的形状
      Box Colider:盒型碰撞器,用于方形物体。
      Capsule Colider:胶囊体碰撞器,用于人形物体。
      Mesh Collider:网格碰撞器,用于复杂游戏对象,或者整个场景添加碰撞器。

    • 碰撞事件
      注意:当IsTrigger勾选后碰撞器不做碰撞检测,两者不会发生碰撞(可穿透),而是做触发检测。

    1. 碰撞相关的三个事件
        //碰撞开始时调用一次
        void OnCollisionEnter(Collision other)
        {
            //刚开始与地面碰撞打印一次,之后每次碰撞打印一次
            print ("碰撞开始");
        }
    
        //碰撞结束时调用一次
        void OnCollisionExit(Collision other)
        {
            print("碰撞结束");
        }
    
        //当碰撞持续发生时调用
        void OnCollisionStay(Collision other)
        {
            //刚开始与地面碰撞打印了20次,是因为为Cube刚与地面接触还有轻微位移
            //完全静止后不再碰撞
            //只有在有相对位移时打印
            print("碰撞进行中");
    
            //检测与哪个物体发生了碰撞
            //other.gameObject.name;
            //other.gameObject.tag;
            if(string.Equals("Cube2", other.gameObject.name))
           {
                print ("产生火花");
    
            }
        }
    

    2.触发器相关的三个事件
    触发器可以被进入,表示要触发事件的一个范围。类似于地雷的范围。

        //刚进入触发范围时调用一次
        void OnTriggerEnter(Collider other)
        {
            print ("进入触发范围");
        }
    
        //持续停留在触发范围内会一直调用
        void OnTriggerStay(Collider other)
        {
            print ("持续触发");
        }
    
        //离开触发范围时调用一次
        void OnTriggerExit(Collider other)
        {
            print ("离开触发范围");
        }
    
    

    10. 物理材质

    • 物理材质能够给物体添加摩擦力和弹力。
    • 物理材质只能够添加到带有Colider的对象上。(Collider面板中的的Material选项)
    • Assets - New - Physical Material
    • 面板:
      Dynamic Friction:动摩擦力(0,∞),滑动时受到的摩擦力。
      Static Friction:静摩擦力,停留在物体表面受到的摩擦力。
      Bounciness:(0,1),弹力。
      Friction Combine:两个物体相互作用时摩擦力的取值方式。
      Bouncy Combine :两个物体相互作用时弹力的取值方式。
      结合方式:
      Average:结合后的值为两者的平均值
      Minimum:取最小值
      Multiple:相成
      Maximum:取最大值

    11. 射线

    • 虚拟射线能够检测所碰撞到的物体。
    • Physics类的Raycast方法实现。
    public class PlayerController : MonoBehaviour {
    
        /*场景中鼠标点击地面后,角色移动到目标位置*/
        public float speed; //每秒移动多少个单位,数值可在脚本Component的面板中修改
    
        private Vector3 target;//目标位置
        private bool isOver = true; //移动是否结束
    
        void Update () {
            if (Input.GetMouseButtonDown (0)) {
                //1. 获取鼠标点击时的目标位置
                //使用射线实现,鼠标2D场景3D,点击时系统不知道到底点在高的哪个位置
                //从当前视角(当前摄像机作为起点)发出一条射线,穿过鼠标的位置与地面发生碰撞
                                                            //碰撞点为移动位置
    
                //a.创建射线
                //Ray ray = new Ray();
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
                                          //摄像机射出的射线经过某一点(鼠标位置点)
    
                //b.发射射线
                RaycastHit hitinfo = new RaycastHit();
                Physics.RaycastAll;//返回视线经过的所有物体的数组
    
                if(Physics.Raycast(ray,out hitinfo)) 
                            //Physics.Raycast返回bool,能否碰到游戏对象,返回首次碰到的物体
                {
                    //获取碰撞点的位置
                    //检测碰撞点是否为地面。hitinfo中
                    if(hitinfo.collider.name == "Plane"){
                        target = hitinfo.point; //hitinfo.point为hitinfo保存的碰撞点的位置
                        target.y = 0.5f; //让cube保持在地面上
                        isOver = false;
                    }
                }       
            }
    
            //2. 让角色移动到目标位置
            MoveTo (target);
        }
    
        //让角色移动到目标位置
        private void MoveTo(Vector3 tar){
            if (!isOver) {
                Vector3 vi =    tar - transform.position;
                transform.position += vi.normalized * speed * Time.deltaTime;  
                               //方向*大小*每秒规律执行,deltatime与帧无关,按秒计
                if(Vector3.Distance(tar, transform.position) <= 0.1f){ 
                                  //目标位置与当前位置小于某个值,完全相等几率很低
                    isOver = true;
                    transform.position = tar;
                
              }
            }
        }
    }
    

    相关文章

      网友评论

      • 豪门百里:竟然一开始就说不认识的词,让人感觉很喜感= =

      本文标题:Unity基础

      本文链接:https://www.haomeiwen.com/subject/vvdgdttx.html