• Unity3D课程学习笔记(一) 1.解释游戏对象(GameObjects)和资源(Assets)的区别与联系 官方文档对Assets的解释:An asset is representation of any item that can be used in your game or project. An asset ...

    Unity3D课程学习笔记(一)

    1.解释游戏对象(GameObjects)和资源(Assets)的区别与联系

    官方文档对Assets的解释:An asset is representation of any item that can be used in your game or project. An asset may come from a file created outside of Unity, such as a 3D model, an audio file, an image, or any of the other types of file that Unity supports. There are also some asset types that can be created within Unity, such as an Animator Controller, an Audio Mixer or a Render Texture.

    官方文档对GameObjects的解释:GameObjects are the fundamental objects in Unity that represent characters, props and scenery. They do not accomplish much in themselves but they act as containers for Components, which implement the real functionality.

    解释区别与联系:对象一般是一些资源的集合体,是资源整合的具体表现,而资源可以被多个对象使用。游戏对象一般为玩家,敌人,环境等,而资源可组成游戏中所有的对象,一般包括声音,脚本,材质等,资源可以被多个对象使用,资源作为模版,可实例化游戏中具体的对象。

     

     

    2.下载几个游戏案例,分别总结资源、对象组织的结构(指资源的目录组织结构与游戏对象树的层次结构)

       游戏:Beat-Plane:如下图所示结构,资源中可以放置图像、声音、脚本等。

     

     

    3.编写一个代码,使用 debug 语句来验证 MonoBehaviour 基本行为或事件触发的条件

    测试代码如下所示:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Test : MonoBehaviour {
    	void Awake() {
    		Debug.Log ("In Awake!");
    	}
    
    	// Use this for initialization
    	void Start () {
    		Debug.Log ("In Awake!");
    	}
    	
    	// Update is called once per frame
    	void Update () {
    		Debug.Log ("In Update!");
    	}
    
    	void FixedUpdate() {
    		Debug.Log ("In FixedUpdate!");
    	}
    
    	void LateUpdate() {
    		Debug.Log ("In LateUpdate!");
    	}
    
    	void OnGUI() {
    		Debug.Log ("In OnGUI!");
    	}
    
    	void OnDisable() {
    		Debug.Log ("In OnDisable!");
    	}
    
    	void OnEnable() {
    		Debug.Log ("In OnEnable!");
    	}
    }
    

    则该代码运行后在Console中显示如下所示:

     

    MonoBehaviour 基本行为或事件触发的条件(按执行顺序):

    Awake() : 当前控制脚本实例被装载的时候调用。一般用于初始化整个事例使用。(建议少用,此刻物体还未实例化出来,会影响程序的执行顺序)

    Start() : 当前控制脚本第一次执行Update之前调用。

    Update() : 每帧都执行一次,是最常用的时间函数。

    FixedUpdate() : 每固定帧绘制时执行一次,和Update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率底下的时候FixedUpdate的调用次数就会下降。FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关,而Update比较适合做控制。(放置游戏基本物理行为的代码,在Update之后执行)

    LateUpdate() : 在每帧执行完毕调用,他在所有Update结束后才调用,比较适合于命令脚本的执行。官网上例子是摄像机的跟随,都是在所有Update操作完才跟进摄像机,不然就有可能出现摄像机已经推进了,但是视角里还未有角色的空帧出现。

    OnEnable() : 当对象变为可用或激活状态时此函数被调用,OnEnable不能用于协同程序。(物体启动时被调用)

    OnDisable() : 当对象变为不可用或非激活状态时此函数被调用。当物体销毁时它被调用,并且可用于任意清理代码。当脚本编译完成之后被重新加载时,OnDisable将被调用,OnEnable在脚本被载入后调用。(物体被禁用时调用)

    OnGUI() : 绘制GUI时候触发。一般在这个函数里绘制GUI菜单。(GUI显示函数只能在OnGUI中调用)

     

     

    4.查找脚本手册,了解GameObject,Transfrom,Component对象

    4.1.分别翻译官方对三个对象的描述(Description)

    GameObject :GameObjects are the fundamental objects in Unity that represent characters, props and scenery. They do not accomplish much in themselves but they act as containers for Components, which implement the real functionality.

    翻译:游戏对象是Unity中表示游戏角色,游戏道具和游戏场景的基本对象。他们自身无法完成许多功能,但是他们构成了那些给予他们实体功能的组件的容器。

    Transform :The Transform component determines the Position, Rotation, and Scale of each object in the scene. Every GameObject has a Transform.

    翻译: 转换组件决定了游戏场景中每个游戏对象的位置,旋转和缩放比例。每个游戏对象都有转换组件。

    Component :Components are the nuts & bolts of objects and behaviors in a game. They are the functional pieces of every GameObject.

    翻译: 组件是游戏中对象和行为的细节。它是每个游戏对象的功能部分。

     

    4.2.描述下图中 table 对象(实体)的属性、table 的 Transform 的属性、 table 的部件

    Table对象的属性:Tag属性用于区分游戏中不同类型的对象,Tag可以理解为一类元素的标记,可用GameObject.FindWithTag()来查询对象。GameObject.FindWithTag()只返回一个对象,如果想获取多个Tag为某值的对象,应该用GameObject.FindGameObjectsWithTag()。第一个选择框是activeSelf属性。Layer属性默认是Default。

    Table的Transform属性:Position、Rotation、Scale

    Table的部件:Mesh Filter、Box Collider、Mesh Renderer

     

    4.3.用UML图描述三者的关系:

    UML图如下所示:

     

     

    5.整理相关学习资料,编写简单代码验证以下技术的实现:

    查找对象:

    通过名字查找:

    public static GameObject Find(string name)

    通过标签查找单个对象:

    public static GameObject FindWithTag(string tag)

    通过标签查找多个对象:

    public static GameObject[] FindGameObjectsWithTag(string tag)

    添加子对象:

    public static GameObect CreatePrimitive(PrimitiveTypetype)

    遍历对象树:

    foreach (Transform child in transform) {
    
             Debug.Log(child.gameObject.name);
    
    }

    清除所有子对象:

    foreach (Transform child in transform) {
    
             Destroy(child.gameObject);
    
    }

     

     

    6.资源预设(Prefabs)与 对象克隆 (clone)

    6.1.预设(Prefabs)有什么好处?

    预设类似于一个模板,通过预设可以创建相同属性的对象,这些对象和预设关联。一旦预设发生改变,所有通过预设实例化的对象都会产生相应的变化(适合批量处理)。

    6.2.预设与对象克隆 (clone or copy or Instantiate of Unity Object) 关系?

    对象克隆不受克隆本体的影响,因此A对象克隆的对象B不会因为A的改变而相应改变。

    6.3.制作 table 预制,写一段代码将 table 预制资源实例化成游戏对象

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class shilihua : MonoBehaviour {
    	public GameObject MyTable; 
    
    	// Use this for initialization
    	void Start () {
    		GameObject instance = (GameObject)Instantiate(MyTable, transform.position, transform.rotation);
    	}
    
    	// Update is called once per frame
    	void Update () {
    
    	}
    }

     

     

    7.尝试解释组合模式(Composite Pattern / 一种设计模式)。使用 BroadcastMessage() 方法向子对象发送消息

    组合模式允许用户将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。

    子类对象方法:

      void recallMessage() {
             print("Hello!");
     }

    父类对象方法:

     void Start () {
             this.BroadcastMessage("recallMessage");
     }

     

     

    8.编程实践,井字棋小游戏

    井字棋小游戏其实只是一个2D游戏,具体实现过程并不是很难,主要是要掌握GUI的一些API的使用

    本次作业主要用到GUI的一些API,GUI是指Graphic User Interface,是图形用户接口,主要提供可视化界面方面的接口

    具体代码实现如下:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Chess : MonoBehaviour {
    	private int [,] chessBoard = new int[3,3];
    	private int turn = 1;
    	// Use this for initialization
    	void Start () {
    		Reset ();
    	}
    
    	void OnGUI() {
    		if(GUI.Button(new Rect(400,50,150,50),"RESET GAME")) {
    			Reset();
    		}
    
    		//First judge the result.
    		int State = checkWhetherIsWin ();
    		if (State == 2) {
    			GUI.Label (new Rect (400, 105, 50, 50), "X Win!");
    		} else if (State == 1) {
    			GUI.Label (new Rect (400, 105, 50, 50), "O Win!");
    		} else if (State == 0) {
    			GUI.Label (new Rect (400, 105, 50, 50), "Tied!");
    		}
    
    		//The Game is not over,continue.
    		for(int i = 0 ; i < 3 ; i++) {
    			for (int j = 0; j < 3; j++) {
    				//If the number of the chessboard is 1, it represents O, else 2 represents X.
    				if (chessBoard[i,j] == 1) {
    					GUI.Button (new Rect (400 + 50 * i, 130 + 50 * j, 50, 50), "O");
    				} else if (chessBoard[i,j] == 2) {
    					GUI.Button (new Rect (400 + 50 * i, 130 + 50 * j, 50, 50), "X");
    				}
    
    				//Click operation.
    				if(GUI.Button(new Rect(400+50*i,130+50*j,50,50),"")) {
    					if(State == 3) {
    						if (turn == 1) {
    							chessBoard [i, j] = 1;
    						} else if (turn == -1) {
    							chessBoard [i, j] = 2;
    						}
    						turn = -turn;
    					}
    				}
    			}
    		}
    	}
    
    	int checkWhetherIsWin() {
    		//Check the rows.
    		for (int i = 0; i < 3; i++) {
    			if (chessBoard[i,0] == chessBoard[i,1] && chessBoard[i,0] == chessBoard[i,2] && chessBoard[i,0] != 0) {
    				return chessBoard[i,0]; //1
    			}
    		}
    
    		//Check the columns.
    		for (int j = 0; j < 3; j++) {
    			if (chessBoard[0,j] == chessBoard[1,j] && chessBoard[0,j] == chessBoard[2,j] && chessBoard[0,j] != 0) {
    				return chessBoard[0,j]; //2
    			}
    		}
    
    		//Check the diagonals.
    		if(chessBoard[0,0] == chessBoard[1,1] && chessBoard[0,0] == chessBoard[2,2] && chessBoard[0,0] != 0) return chessBoard[0,0];
    
    		if(chessBoard[0,2] == chessBoard[1,1] && chessBoard[0,2] == chessBoard[2,0] && chessBoard[0,2] != 0) return chessBoard[0,2];
    
    		//Judge whether the game is tied.
    		int count = 0;
    		for(int i = 0 ; i < 3 ; i++) {
    			for (int j = 0; j < 3; j++) {
    				if (chessBoard[i,j] != 0) {
    					count++;
    				}
    			}
    		}
    		if (count == 9) {
    			return 0;
    		}
    		return 3; //3
    	}
    	
    	// Update is called once per frame
    	void Update () {
    		
    	}
    
    	void Reset() {
    		turn = 1;
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				chessBoard[i,j] = 0;
    			}
    		}
    	}
    }

    游戏的UI如下所示:

     

     

     

     

     

     

    展开全文
  • 2016-8-1 学习Unity3D笔记

    2016-08-02 17:27:48
    Unity 中,所有的物理运算都是使用固定时间的*在实际应用中,尽量在速度上使用 Time.deltaTime 目的是为了速度平衡*当变量在脚本类中的属性为 PUBLIC 的时候,可以在Unity编辑器中查看并修改*在

    Update() 与 FixedUpdate() 的区别:

    Update() 是每帧调用一次,一般用于非物理运动
    FixedUpdate() 是每隔固定时间调用一次,一般用于物理运动。在Unity 中,所有的物理运算都是使用固定时间的

    *在实际应用中,尽量在速度上使用 Time.deltaTime 目的是为了速度平衡

    *当变量在脚本类中的属性为 PUBLIC 的时候,可以在Unity编辑器中查看并修改

    *在任何脚本中,如果脚本被赋予GameObject的话,肯定会激活它的 Awake() 方法,如果激活,则会调用 Start()方法
    *开发者可以在 Reset()方法中写入当前脚本变量的初始值(default)
    *[SerializeField] 和 [HideInInspector] :

    放在 [SerializeField]下的变量是可以在编辑器中被发现的,而放在[HideInInspector]下的变量是被隐藏的
    • GameObject.Find(“Object名称”);的方法来获取一个GameObject,类似于CSS中的id
    • GameObject.FindGameObjectWithTag(“”):是通过Object 的 Tag 标签内容来进行查找和操作的,这种情况更像是 CSS 中的 class。
    Transform
    • 在坐标系中,有 Right Up Forward三个变量,分别代表 当前物体的X,Y,Z轴,与世界坐标系是不同的。
    • 函数:
    *TransformPoint() : 将当前坐标转换为世界坐标值
    *InverseTransformPoint():将世界坐标系坐标转化为某物体的坐标
    *TransformDirection():将某物体的方向向量转化为世界坐标系中的方向向量
    *InverseTransformDirection()://将某物体的世界坐标系中的方向向量转化为该物体的方向向量
    *另外补充一个在Unity中引入第一人称的方法:在Assets中引入包:Character中的FirstPersionCharactorm,再把其Prefabs中的FPSController拖入到Hierarchy中即可(将主相机去掉MainCamera)
    
    笔记未完待续。。
    展开全文
  • Unity学习笔记Unity 3D 飞机大战 1、打开unity软件后,首先新建Quad作为背景,导入飞机模型,并为其添加刚体 然后创建C#脚本,挂载到飞机上。 2、给飞机创建子弹,让子弹成为预制体,同样创建C#脚本 3、创建陨石和...

    Unity学习笔记:Unity 3D 飞机大战

    1、打开unity软件后,首先新建Quad作为背景,导入飞机模型,并为其添加刚体
    然后创建C#脚本,挂载到飞机上。
    2、给飞机创建子弹,让子弹成为预制体,同样创建C#脚本
    3、创建陨石和敌机作为敌方,飞机发射子弹使其销毁,如果飞机与敌方相撞,则飞机爆炸消失。

    放上完成后的图:
    在这里插入图片描述
    给飞机设置的组件:
    alt
    子弹的组件:
    在这里插入图片描述
    陨石的组件:
    在这里插入图片描述
    敌机和其子弹的组件与飞机类似,就不放图了~

    接下来是代码:
    1、飞机脚本

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    
    /** 玩家飞机飞行的脚本 */
    public class PlayerMovement : MonoBehaviour
    {
        /** 飞机可以飞行的区域 */
        public float xMax;
        public float xMin;
        public float zMax;
        public float zMin;
    
        /** 飞机自身的刚体 以及 飞机发射子弹的位置 */
        Rigidbody _plane_rig;           
        Transform _plane_fire_point;
    
        /** 子弹的预制体 */
        GameObject _bullet;
    
        private void Awake()
        {
            //获取刚体
            _plane_rig = this.GetComponent<Rigidbody>();
            //获取开火位置
            _plane_fire_point = transform.GetChild(1);
            //获取子弹的预制体
            //通过资源加载的方式获取预制体
            _bullet = Resources.Load("Prefabs/Bullet") as GameObject;
        }
    
        private void FixedUpdate()
        {
            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");
            //飞机移动
            Move(h, v);
            //飞机开火
            Shoot();
        }
    
        /** 飞机的飞行速度 以及飞机的倾斜度 */
        public float plane_speed = 3f;
        public float plane_Tilt = 2f;
        void Move(float h,float v)
        {
            //1.获取飞机移动的方向
            Vector3 plane_fly_dir = new Vector3(h, 0, v);
            //2.设定飞机的飞行速度
            _plane_rig.velocity = plane_fly_dir * plane_speed;
            //3.移动
            _plane_rig.position = new Vector3
                (
                    //Mathf.Clamp(x,y,z)的作用是将x限定在y和z之间
                    Mathf.Clamp(_plane_rig.position.x,xMin,xMax),
                    5f,
                    Mathf.Clamp(_plane_rig.position.z,zMin,zMax)
                );
            //4.设置飞机倾斜度
            _plane_rig.rotation = Quaternion.Euler(0f, 0f, _plane_rig.velocity.x * -plane_Tilt);
        }
    
    
        float _shoot_rate = 0.5f;
        float _timer = 0f;
        void Shoot()
        {
            //计时
            _timer += Time.deltaTime;
            //按下鼠标左键
            if (Input.GetMouseButton(0) && _timer >= _shoot_rate)
            {
                //在_plane_fire_point.position的位置生成_bullet实例,保持_plane_fire_point.rotation的旋转
                Instantiate(_bullet, _plane_fire_point.position, _plane_fire_point.rotation);
                //重置定时器
                _timer = 0f;
            }
        }
    }
    

    2、子弹的脚本

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class BulletMovement : MonoBehaviour
    {
        /** 子弹的飞行速度 */
        public float bullet_speed = 20f;
    
        private void FixedUpdate()
        {
            this.GetComponent<Rigidbody>().velocity = bullet_speed * transform.forward;
        }
    }
    

    3、陨石的脚本

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class AsteroidMove : MonoBehaviour
    {
        //陨石的移动速度集合
        float[] _asteroid_speeds = { 8, 10, 13, 16 };
    
        private void Awake()
        {
            //左闭右开 [0,4)
            int index = Random.Range(0, _asteroid_speeds.Length);
    
            this.GetComponent<Rigidbody>().velocity = Vector3.back * _asteroid_speeds[index];
        }
    
    }
    

    陨石旋转

     //陨石旋转的速率集合
        float[] rotRations = { 4f, 6f, 8f };
    
        private void Awake()
        {
            int index = Random.Range(0, rotRations.Length);
    
            //Random.insideUnitSphere 随机返回球体(半径为1的球体)内部的任意一点
            this.GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere * rotRations[index];
        }
    
    

    陨石爆炸

    /** 爆炸效果预制体 */
        public GameObject asteroidExp;
        public GameObject playerExp;
    
        private void OnTriggerEnter(Collider other)
        {
            //碰到陨石或者是敌方飞机 不处理直接返回
            if (other.gameObject.tag == "Asteroid" || other.gameObject.tag == "Enemy" || other.gameObject.tag == "EBullet")
                return;
    
            //碰到了子弹
            if(other.gameObject.tag == "Bullet")
            {
                //生成爆炸体
                GameObject exp = Instantiate(asteroidExp, transform.position, transform.rotation);
                //销毁
                Destroy(exp, 0.3f);
            }
    
            //碰到了玩家
            if(other.gameObject.tag == "Player")
            {
                //生成爆炸体
                GameObject exp = Instantiate(playerExp, transform.position, transform.rotation);
                //销毁
                Destroy(exp, 0.3f);
            }
    
            //销毁碰到的物体
            Destroy(other.gameObject);
            //销毁自身
            Destroy(transform.gameObject);
    
        }
    
    

    以及陨石的管理

     /** 三个陨石预制体 */
        GameObject _Asteroid_01;
        GameObject _Asteroid_02;
        GameObject _Asteroid_03;
    
        /** 存放所有的陨石 */
        List<GameObject> _Asteroids;
    
        private void Awake()
        {
            //初始化陨石集合
            _Asteroids = new List<GameObject>();
    
            //通过资源加载的方式先获取到三个陨石
            _Asteroid_01 = Resources.Load("Prefabs/Asteroid_01") as GameObject;
            _Asteroid_02 = Resources.Load("Prefabs/Asteroid_02") as GameObject;
            _Asteroid_03 = Resources.Load("Prefabs/Asteroid_03") as GameObject;
    
            //将三个陨石加入到集合中
            _Asteroids.Add(_Asteroid_01);
            _Asteroids.Add(_Asteroid_02);
            _Asteroids.Add(_Asteroid_03);
        }
    
        private void Start()
        {
            //重复调用某一个方法
            InvokeRepeating("CreateAsteroid", 0f, 3f);
        }
    
        void CreateAsteroid()
        {
            //1.随机从集合中取出陨石
            GameObject asteroid = _Asteroids[Random.Range(0, _Asteroids.Count)];
            //2.创建随机位置
            Vector3 asteroidPos = 
                new Vector3(Random.Range(transform.position.x, -transform.position.x), 5f, 17.52f);
            //3.创建陨石
            Instantiate(asteroid, asteroidPos, Quaternion.identity);
        }
    
        private void OnApplicationQuit()
        {
            //当程序结束的时候取消invoke的重复调用
            CancelInvoke("CreateAsteroid");
        }
    
    

    4、最后是敌机和其子弹

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class EnemyShip : MonoBehaviour {
    
        //敌机的移动速度集合
        float _enemy_speeds = 3f;
        Transform _eplane_fire;
    
        /** 敌机子弹的预制体 */
        GameObject _ebullet;
    
        private void Awake()
        {
            //左闭右开 [0,4)
            this.GetComponent<Rigidbody>().velocity = Vector3.back * _enemy_speeds;
            transform.eulerAngles = new Vector3(transform.eulerAngles.x, 180, transform.eulerAngles.z);
    
            //获取开火位置
            _eplane_fire = transform.GetChild(1);
            //获取子弹的预制体
            //通过资源加载的方式获取预制体
            _ebullet = Resources.Load("Prefabs/EBullet") as GameObject;
    
        }
    
        private void FixedUpdate()
        {
            //敌机开火
            Shoot();
        }
    
        float _shoot_rate = 2f;
        float _timer = 0f;
        void Shoot()
        {
            //计时
            _timer += Time.deltaTime;
            if (_timer >= _shoot_rate)
            {
                //在_plane_fire_point.position的位置生成_bullet实例,保持_plane_fire_point.rotation的旋转
                Instantiate(_ebullet, _eplane_fire.position, Quaternion.identity);
                //重置定时器
                _timer = 0f;
            }
        }
    }
    

    (敌机的爆炸及其子弹的爆炸和陨石爆炸代码类似,下面就不放了)


    5、最后的最后(终于要完成了~)给敌机设置管理

    /** 敌机 */
        GameObject _enemys;
    
        private void Awake()
        {
            //通过资源加载的方式先获取到敌机
            _enemys = Resources.Load("Prefabs/EnemyShip") as GameObject;
        }
    
        private void Start()
        {
            //重复调用某一个方法
            InvokeRepeating("CreateEnemy", 0f, 3f);
        }
    
        void CreateEnemy()
        {
            
            //1.创建随机位置
            Vector3 enemyPos =
                new Vector3(Random.Range(transform.position.x, -transform.position.x), 5f, 17.52f);
            //2.创建陨石
            Instantiate(_enemys, enemyPos, Quaternion.identity);
        }
    
        private void OnApplicationQuit()
        {
            //当程序结束的时候取消invoke的重复调用
            CancelInvoke("CreateEnemy");
        }
    

    撒花!!!一个飞机大战小游戏就完成了,用 unity 做这款小游戏有些大材小用,却也的确比用 h5 简单很多!

    展开全文
  • 7.15日 学习笔记 今天是我第一次接触到unity3d,其中我感觉到了简单游戏模型的制作和c#语言在游戏编程的重要性。 上午: 安装了unity3d花了整整一个上午,受益最大的是关于该软件的安装方法对于unity3d的安装和注册...

    7.15日 学习笔记
    今天是我第一次接触到unity3d,其中我感觉到了简单游戏模型的制作和c#语言在游戏编程的重要性。
    上午:
    安装了unity3d花了整整一个上午,受益最大的是关于该软件的安装方法对于unity3d的安装和注册的确需要一些经验才能快速感受到做游戏的乐趣。
    下午:
    通过一个上午视频学习,总觉得视频内容较为简单,但是在下午实际操作却出现种种错误,unity3d需要多种功能合并使用并且其给予初学者的感觉是种类繁多,形式复杂,建立复杂游戏模型需要不断改进方位进程所以有时觉得写入脚本更为轻松,unity3d理论上应是多个辅助软件集合体,如果做出一个好的游戏只有unity3d是远远不够的,虽然unity3d作用软件广泛但功能并不精通,好比今天下午做游戏时出现了关于模型颜色问题,百度上给出的答案是利用ps建立好资源包后再通过unity3d进行塑性,而实际上确实如此unity’3d的改颜色方法虽然有但是改过颜色的模型在不同视角却看起来极其粗糙,刚开始接触c#时觉得类多麻烦,有时甚至不能够理解其作用。如今茅塞顿开。
    晚上:
    晚上完善了下午做的内容,知道了var的声明含义与c#语言在unity3d的对各个不同功能衔接语句,我觉得这是个日益积累的过程,故不积跬步,无以至千里。其实在今天最大的收获是单词的积累。比如scrpit,component,等等(今天不认识的生词太多了)让我知道了学好英语的重要性。

    展开全文
  • Unity3d笔记——利用Animator使模型动起来一. 从Asset Store中下载合适的模型 本篇记录了一个小demo的制作过程,从找模型并下载,到创建Animator,绑定C#脚本,最后实现按下左箭头模型向我们的左边旋转,按下右箭头...


    本篇记录了一个小demo的制作过程,从找模型并下载,到创建Animator,绑定C#脚本,最后实现按下左箭头模型向我们的左边旋转,按下右箭头模型向我们右边旋转的全部过程。希望大家共同学习共同进步。

    一. 从Asset Store中下载合适的模型

    首先点击菜单栏中的window -> asset store,调出Asset Store面板,如下图。在搜索栏中输入自己想要查找的模型即可。
    调出Asset Store面板Asset Store面板
    Tips:可在Asset Store选项卡上右键,选择Maximize,如图

    在Asset Store选项卡上右键,选择Maximize
    在最大化后,可设置筛选选项,我们可以把Price调整为0到0,从而筛选出免费的模型
    筛选免费的模型
    最后,我找到的是一个免费的机器人模型,叫Kyle,如图,点击Download之后,再点击Import即可。(因为我已经下载好,所以图上直接显示了Import)
    下载完的Package一般存放于C:/Users/XXX/AppData/Roaming/Unity/Asset Store/目录中。
    免费的机器人模型

    二. 为模型创建Avatar

    Avatar,它可以实现骨骼和肌肉系统的匹配,从而保证角色在执行动画的时候,角色能够按照预先设定的动画来运动。
    在Project面板中,浏览到Robot Kyle目录下的model文件夹,如图,可看到里面的fbx模型文件
    fbx模型文件
    点击该文件,在它的Inspector面板中,选中Rig选项卡,将Animation Type设为Humanoid,即双足类型的动画,这种类型可以支持大多数的类人形的模型。此外,Lagacy类型用来兼容Unity3D低版本中的模型动画,Generic类型是一种介于人形和非人形的模型之间的通用类型。设置好Humanoid类型后,在下方选择生成Avater的类型为Create Form This Model,即通过当前的模型来生成一个Avater。创建好后,即可看见该模型中,增加了一个Avatar。

    Inspector面板模型
    点击该Avatar,Inspector面板如图所示,我们可以通过点击Configure进行编辑和查看骨骼绑定是否正确。若无误,点击Done即可。
    Inspector面板
    Configure

    三. 增加AnimatorController文件

    如果说Avater是将模型的身体和骨骼实现匹配的接口,那么AnimatorController就是将动画和模型实现绑定的接口。
    在Project面板中,相应的位置,右键,添加一个AnimatorController文件,并命名为RobotAnimatorController,如下图
    添加AnimatorController文件
    双击该文件,会弹出Animator面板,初始状态下,只有Entry,和Any State两个状态,这里会涉及到一个概念:States(动画状态),其实这也就是一个有限状态机,在进入每一个State之前,会有一个判断条件是否进入,当判断条件达到,则满足该状态,进行该状态的动画播放。
    Entry(Animator入口)—>DefaultState(默认状态)—>Next State(满足条件的下一个状态)—>Exit(离开状态)

    我们在空白位置,右键,新建一个状态,如图所示
    新建一个状态
    点击该状态,我们在Inspector面板中,可对它进行设置,将其命名为Idle。
    Inspector面板
    并在Motion中进行动画的绑定。我们可以利用标准资源包Standard Assets中的Characters下的ThirdPersonCharacter,里面自带了很多人物模型的动画。(自己制作动画参见我的另一篇笔记
    Standard Assets
    ThirdPersonCharacter
    点击State的Inspector面板中Motion一行最右边的小圆圈,会自动弹出该项目下所有的动画,选择其中合适的一个即可,我选择的是HumanoidIdle,如图
    HumanoidIdle
    配置好我们新建的名为Idle的State后,将其设置为默认状态,代表在正常状态下是执行这个State的动画,在Entry状态上右键,选择make Transition,并连接到Idle状态,如图
    make Transition
    设置好后,一个AnimatorController文件就算制作完成。

    四. 将AnimatorController文件与游戏对象相结合

    我们将该fbx模型拖拽到hierarchy面板中,即创建了一个游戏对象Object,并能在Scene中观察到它,如图
    在这里插入图片描述
    点击该游戏对象,在Inspector面板中,我们为其增加一个Animator组件,配置Controller为RobotAnimatorController,Avtar为Robot KyleAvtar,如下图
    增加一个Animator组件
    最后,点击运行按钮,就可以看到机器人悠闲的动起来了。(因为不会放动态图,就不放了)

    五. 利用C#脚本实现按下方向键模型向相应方向旋转

    首先,在我们创建的RobotAnimatorController文件中,增加两个State,OnRightArrow与OnLeftArrow,并在Motion处绑定往相应方向旋转的动画,最后将这几个状态连接起来,如下图
    RobotAnimatorController
    OnRightArrow OnLeftArrow
    接下来,我们给这个Animator添加一个状态字:在Animator面板中,选择Parameters选项卡,点击搜索框右边的小加号按钮,选择一个Int类型的状态字,并命名为ActionID,默认值为0,如下图
    选择一个Int类型的状态字
    然后,我们选中其中一个Transition,就拿Idle->OnLeftArrow这个Transition为例,我们选中它,然后在Inspector面板中的Condition里,增加一个判断条件,参数为ActionID,行为是Equals ,值为1,意思是,当ActionID这个值为1的时候,Animator就会执行从此Transition的源State到此Transition的目标State,即Idle到向我们的左边旋转的状态,两个动画之间的转换过程也可在Settings中进行修改,如图所示
    Transition
    最后,新建一个C#脚本,实现按下相应方向键,改变ActionID的值,从而触发Animator执行两个不同动画间的转换,代码如下

    using UnityEngine;
    public class RobotBehaviourScript : MonoBehaviour {
    	private Animator m_Animator = null;
    	
    	// Use this for initialization
    	void Start () {
    		m_Animator = GetComponent<Animator>();
    	}
    
    	// Update is called once per frame
    	void Update () {
    		if (Input.GetKeyDown(KeyCode.LeftArrow))
    			m_Animator.SetInteger("ActionID", 1);
    		if (Input.GetKeyDown(KeyCode.RightArrow))
    			m_Animator.SetInteger("ActionID", 2);
    		if (Input.GetKeyDown(KeyCode.Space) | Input.GetKeyDown(KeyCode.DownArrow))
    			m_Animator.SetInteger("ActionID", 0);   
    	}
    }

    至此,这个小demo就算完成啦!

    参考博客:https://blog.csdn.net/nizihabi/article/details/48998087

    展开全文
  • Unity中的组件上的类,是不能new的,必须通过组件去获取,new出来的东西是null。  if (amainfo.nameHash == Animator.StringToHash(Base Layer.idle))  {  m_animator.SetBool(Run, true);  }  代码无法执行时...
  • 最近刚刚开始接触unity3d,因此想把自己的学习路线记录下来,方便自己以后总结。由于毕业论文的关系,需要使用Unity3D开发,做虚拟现实的应用,使用的设备是HTC vive pro产品。初始学习,由于没有基础,因此一团乱,...
  • 一、解释对象与资源的区别与联系,根据官方案例,分别总结资源和对象组织的规则/规律资源指的是游戏中那些直接可见的、对用户展现出的元素,包括图片、音乐、视频、人物、字体。 对象指的是数据?...
  • Unity3D学习笔记(2)Unity3D与3DMax结合开发注意事项 单位:比例统一 在建模型前先设置好单位,在同一场景中会用到的模型的单位设置必须一样,模型与模型之间的比例要正确,和程序的导入单位一致,即便到程序...
  • Unity3D学习笔记总结

    2013-12-21 21:34:06
    编辑器: Hierarchy窗口中是场景中的Game Object列表 Project窗口中是磁盘上Assets文件夹中的内容,可用来创建Game Object 调试: ...因Unity采用的是Mono运行时引擎而不是CLR,参考Debugging us
  • Unity3D学习路线与学习经验分享//最后一次更新为2019.7.22日,更新了一些废掉的链接 作者:15游02 丁祺 你好,这篇文档是我的导师孙老师(以下简称老孙)指名我 书写给新手、初学者以及技能有些许缺陷的人的一篇...
  • Unity3D Unity基本操作 Unity基本单位为米,ue4是厘米 Rotation 为度,监事面板是角度,代码里计算的结果是弧度 Scale的单位是倍数。负数为左右镜像   创建工程 必要文件夹: Sences Scripts Prefabs  ...
  • 1、基础知识: 标题栏 菜单栏 工具栏:变换工具、gizmos切换、播放控件、层列表、布局列表 功能窗口 2、资源及资源类型:在project里面能够...maya、3dmax创建的模型、动画,用插件输出(fbx、obj)或者软件自己的格...
  • 最近开始在学习Unity3D,在网上找到了一些教程利用晚上回家休息的时间自学了一下,我就是一个小白,对Unity3D什么都不懂,可能需要一些美工的功底。刚好有点,需要点编程的基础,也好我也有点,对C#很熟,看着Unity...
  • Unity3D】ShaderLab学习笔记 1、什么是Shader: Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(多边形网格,一般使用三角形)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元...
  • Unity3d学习笔记

    2013-04-12 19:54:32
    Unity3d里只包含一个默认字体文件来说吧!Arial字体,对于中文的支持糟糕透了。所以,我们要自己指定GUI的Skin。这样整下GUI可以使用统一风格的GUI。  首先导入要使用的字体,然后创建自已的GUI Skin文件mySkin...
  • C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型 遇到一个想做的功能,但是实现不了,核心原因是因为对U3D的3D数学概念没有灵活吃透。故再次系统学习之第三次学习3D数学.   ...
  • 如果你接触过《设计模式》、软件架构的编程思想,就会知道优秀的设计准则:“组合优于继承的”。 这句话很简短,但开始学习OOP的时候,真切的是—-不太好理解(以我个人当初学习为例)。
  • Unity3D课程学习笔记

    2019-06-20 14:24:16
    Unity3D课程学习笔记(一)1.解释游戏对象(GameObjects)和资源(Assets)的区别与联系官方文档对Assets的解释:An asset is representation of any item that can be used in your game or project. An asset may ...
  • Unity3d_学习笔记_入门

    2013-03-26 17:12:13
    要利用Unity3d开发游戏,我们首先要下载一个Unity3d软件。下载后,下载一个破解补丁,这样就可以正常进行开发了。 2、Unity3d每次只能开启一个工程项目。 (1)Unity3d中比较重要的一个对象就是摄像机了,摄像机就...
1 2 3 4 5 ... 20
收藏数 4,107
精华内容 1,642