Unity面向组件开发

Unity面向组件开发

##1Unity组件开发java

++1.1、工程与应用程序node

++++新建立的Unity工程,在其目录文件夹中包含4个文件夹。数据库

-- Assets: 里面存放的是项目所须要的资源;编程

-- Library: 里面存放的是所须要的库文件;设计模式

-- ProjectSettings: 里面存放的是工程设置文件;数组

-- Temp: 里面存放的是临时文件;网络

++1.2Unity工程开发框架框架

++++工程,场景,游戏对象和组件的关系编程语言

-- 一个工程里面有多个场景,至关于一个游戏有多个关卡;编辑器

-- 一个场景里面有多个游戏对象,至关于游戏中的不一样元素;

-- 每一个游戏对象又有一个或者多个组件,游戏对象想要实现什么样的功能只须要加上相对应的组件便可;


++1.3Unity面向组件开发思想

++++Unity面向组件开发,游戏物体想要实现什么样的功能,只须要添加相对应的组件便可,此时会在Inspector面板中显示出来,一些属性值能够可视化的更改。

-- Transform组件,决定物体的位置,旋转和缩放。

-- Mesh Filter组件,选择网格。

-- Box Collider组件,用来给物体添加碰撞器。

-- Mesh Renderer组件,能够给物体添加材质,纹理以及渲染的方式。


++1.4、脚本组件的使用

++++脚本组件开发工具

-- Unity自带脚本编辑器,建立Mono应用程序,适用于LinuxMac OS XWindows的继承开发环境,支持C#BOOJavaScript等高级编程语言。

-- 微软公司的开发工具包,包括了整个软件生命周期中须要的大部分工具,如团队开发工具、集成开发环境等等。

-- Unity中经过菜单设置修改默认的脚本编辑器: 【Edit=>Preferences=>External Tools=>External Script Editor

++++脚本组件

   -- 脚本是一种特殊的组件,它用于添加到游戏对象上以实现用户自定义的一些功能。

++++脚本的建立

-- Project视窗Asset文件夹中点击右键,建立C#脚本,而后把建立的脚本拖到游戏物体上便可。

++++脚本的使用

-- 双击建立的脚本组件,便可打开脚本

using UnityEngine;

using System.Collections;

 

pulbic class CubeScript : MonoBehaviour{

    //注:类名与脚本组件名一致,并自动的继承MonoBehaviour类,类名与脚本名不同会出错。

}


++2Unity脚本组件

++2.1Unity脚本类

++++Unity中的经常使用脚本类就能够简单的分红以下四大类:

Unity脚本类  --宏观控制类

             -- 游戏对象类

             -- 组件类

             -- 资源类

++++宏观控制类: 主要做用是针对Unity程序中的某一方面进行宏观控制。包括应用程序类(Application)、输入类(Input)、图形输出类(GUI)、物理引擎类(Physics)、资源类(Resources)、时间类(Time)等。

++++游戏对象(GameObject)类: 表示当前脚本挂在的游戏对象。

++++组件(Component)类: 脚本开发中的组件类每每能够和图形界面界面中的检视面板对应起来。 每个游戏对象的细节设置与操控都须要借助组件类来完成。

++++资源类: 资源通常都是在图形界面导入进来以后直接使用。

++2.2MonoBehaviour

++++Unity脚本组件必须继承MonoBehaviour类。

++++继承自MonoBehaviour的脚本组件能够自动调用其封装好了的回调方法。

++2.3、脚本生命周期


++MonoBehaviour类经常使用方法

++++初始阶段:Awake()OnEnable()Start()

++++物理阶段:FixedUpdate()

++++游戏逻辑:Update()LateUpdate()

++++场景渲染:OnGUI()OnBecameVisible()OnBecameInvisible()

++++结束阶段:OnDisable()OnDestroy()OnApplicationQuit()

 

++++初始阶段

-- Awake() 唤醒: 当物体载入时当即调用1次,经常使用于在游戏开始前进行初始化,能够判断当知足某种条件执行此脚本this.enable=true

-- OnEnable() 当可用: 每当脚本对象启用时调用。

-- Start()  开始:物体载入且脚本对象启用时被调用1次。经常使用于数据或游戏逻辑初始化,执行时机晚于Awake

 

++++物理阶段

-- FixedUpdate() 固定更新: 脚本启用后,固定时间被调用,适用于对游戏对象作物理操做,例如移动等。

      设置更新频率: Edit=>Project Setting=>Time=>Fixed Timestep】值,默认为0.02s


++++游戏逻辑

--Update()更新: 脚本启用后,每次渲染场景时调用,频率与设备性能及渲染量有关。

--LateUpdate()延迟更新: 在Update函数被调用后执行,适用于跟随逻辑。

 

++++场景渲染

-- OnGUI() 渲染: 渲染和处理GUI事件时调用。

-- OnBecameVisible() 当可见: 当Mesh Renderer在任何相机上可见时调用。

-- OnBecameInvisible() 当不可见: 当Mesh Renderer在任何相机上不可见时调用。

++++结束阶段

-- OnDisable() 当不可用:对象变为不可用和附属游戏对象非激活状态时此函数被调用。

-- OnDestroy() 当销毁: 当脚本销毁或附属的游戏对象被销毁时调用。

-- OnApplicationQuit() 当程序结束: 应用程序退出时被调用。


++2.4、经常使用调试方法

++++在学习或使用Unity时常常会调试,调试的方式大约有两种:

-- 第一种: 在可能出错的行添加断点

--第二种:选择打印消息的方式

  经常使用打印消息的方式:一种是print,一种是Debug.Log

      -- print方法:它是MonoBehaviour类的成员。

      -- Debug方法: 则是一个独立、密闭的类。


##3、经常使用类

APIApplication Programming Interface)应用程序编程接口,是一些预先定义的函数。Unity引擎提供了丰富的组件和类库,为开发者提供了很是大的便利,熟练掌握和使用这些API对于游戏开发效率提升很重要。

++3.1Component

++++gameObject :组件附加的游戏对象。组件老是被附加到游戏对象上。

++++transform :附加到此游戏对象Transform组件(若是没有则为空)。

++++tag :此游戏对象的标签。

++++collider :附加到此游戏对象的Collider(如无附加则为空)。

++++renderer :附加到此游戏对象Renderer组件(若是没有则为空)。

++++rigidbody :附加到此游戏对象Rigidbody组件(若是没有则为空)。

++++GetComponent :若是游戏对象有附加type类型的组件,则返回,若是没有则为空。

++++GetComponentInChildren :返回此游戏对象上type类型的组件或任何它的子对象,使用深度首先搜索。

++++GetComponents :返回此对象type类型的全部组件。

++++GetComponentsInChildren :返回此游戏对象与其子对象全部type类型的组件。

++3.2GameObject


++++脚本中获得游戏对象

-- 经过tag获得游戏物体

  static GameObject FindWithTag(string tag)

  => GameObject.FindWithTag(“Player”);

-- 经过name获得游戏物体

  static GameObject Find(stirng name)

  => GameObject.Find(“char_ethan”);

++++经常使用属性和方法

-- tag :可读写属性,游戏物体的tag

-- name :可读写属性,游戏物体的name

-- FindGameObjectsWithTag(string tag) :静态方法,返回全部tag标识的物体,返回值是个数组。

-- T GetComponent<T>() :泛型实例方法,获得T类型的组件(强烈建议使用)。

-- SetActive(bool value) :实例方法,设置游戏物体是不是活动的。

-- FindWithTag(string tag) :静态方法,获得tag标识的游戏物体。


++3.3Transform


++++Transorm组件做用:

--1、负责游戏对象的变换(位置,旋转和缩放)

--2、维持父子关系

++++经常使用属性:

--position :世界坐标系中transform的位置

--localPosition :相对于父物体的位置

--eulerAngles :欧拉角,旋转的角度

--rotation :世界坐标系中变换的四元数

--parent :物体父物体的Transform组件

--root :物体最高层次父物体的Transform组件

++++经常使用方法:

-- void Translate(Vector3 translation) :使当前对象朝translation

-- void Rotate(Vector3 eulerAngles) :按给定的欧拉角进行旋转

-- void RotateAround(Vector3 point, Vector3 axis, float angle) :绕point点沿axis轴旋转angle

-- Transform Find(string name) :经过名字查找子物体

-- void LookAt(Transform target) :使物体朝向target

++3.4Vector3

++++点乘

又称“点积”或“内积”。

公式:各份量乘积和 [x1,y1,z1]*[x2,y2,z2] = x1x2 + y1y2 + z1z2

几何意义: a*b = |a|*|b|cos<a,b> 两个向量的单位向量相乘后再乘以两者夹角的余弦值。

APIfloat dot = Vector3.Dot(Va, Vb);

++++点乘应用

对于标准化过的向量,点乘结果等于两向量夹角的余弦值。

应用:计算两向量夹角

float dot = Vector3.Dot(a.normalized, b.normalized);

float angle = Mathf.Acos(dot)*Mathf.Rad2Deg;

++++叉乘

又称“叉积”或“外积”。

公式:

各份量乘积和 [x1,y1,z1]*[x2,y2,z2] = [y1*z1 - z1*y2,  z1*x2 - x1*z2,  x1*y2-y1*x2]

几何意义:结果为两个向量所组成面的垂直向量,模长为两向量模长积乘再乘夹角的正弦值。

脚本: Vector vector = Vector3.Cross(a, b);

++++叉乘应用

建立垂直于平面的向量。

判断两条向量相对位置。

++++Vector3 是封装了向量运算相关变量和方法的结构体。

--normalized :标准化向量,方向不变,长度为1(只读)

--magnitude :向量长度(只读)

--sqrMagnitude :向量长度平方(只读)

--forward Vector(0,0,1)的简码,Z轴正方向

--up Vector(0,1,0)的简码,Y轴正方向

--right Vector(1,0,0)的简码,X轴正方向

--void Normalize() :标准化向量,长度为1

--static Vector3 Lerp(Vector3 from, Vector3 to, float t) :两个向量之间的线性差值

--static float Angle(Vector3 from, Vector3 to) :两个向量之间的夹角

--static float Distance(Vector3 a, Vector3 b) :两向量之间的距离


++3.5Quaternion

++++identity :该四元数无旋转,经常使用在代码建立对象

++++LookRotation :建立一个旋转,沿着forward(z)而且头部沿着upwards(y)的约束注释

++++四元数左乘向量,表示将该向量按照四元数表示的角度旋转。

++++例如: Vector3 point = new Vector3(0,0,10);

           Vector3 newPoint = Quaternion.Euler(0,30,0)*point;

++++避免万向节死锁:

--this.transform.rotation *= Quaternion.Euler(0,1,0);  //使物体沿自身Y轴旋转

--this.transform.Rotate(Vector3 eulerAngles);  //内部就是使用四元数相乘实现


++3.6Time

++++time :从游戏开始到如今所用的时间(只读)

++++deltaTime :获取上一次Update()方法执行的时间到本次执行Update()方法时间的差值

++++fixedDeltaTime :在物理和其余固定帧速率进行更新上一帧所消耗的时间,以秒计算

++++timeScale :表示事件缩放,正常时间为1


++3.7Mathf

++++C#脚本中,Mathf是封装了常见数学计算方法的结构体。

--Lerp :两个浮点数之间进行插值

--Clamp :返回一个限制值

--Sin :计算并返回浮点型的正弦值

--Cos :计算并返回浮点型的余弦值

--Abs :计算并返回指定参数的绝对值

--Max :返回两个值之中最大的值

--Min :返回两个值之中最小的值

--Sqr :返回平方根

--PI :圆周率


++拓展1:《Translate

++++1Space.self: [单位向量= 三维坐标]

-- transform.Translate(transform.forward * Time.deltaTime);

  移动方向为(两向量相加):自身在世界坐标系的方向(向量)+自身的前方(向量)

-- transform.Translate(transform.position * Time.deltaTime);

  移动方向为(单向量):自身在世界坐标系的方向向量

-- transform.Translate(target.forward * Time.deltaTime);

  移动方向为(单向量):目标的前方

-- transform.Translate(target.position * Time.deltaTime);

  移动方向为(单向量):目标在世界坐标系的方向向量

++++2Space.world

同理


++拓展2:《理解Gameobject, gameObject, Transform, transform的区别和关联》

++++1GameObjectgameObject

--GameObject是一个类型,全部的游戏物件都是这个类型的对象。

--gameObject是一个对象,就跟java里面的this同样,指的是这个脚本所附着的游戏物件

--示例

  public class ShowSliderValue:MonoBehaviour{

      private GameObject obje;  //定义GameObject类型的指针

      void Start(){

          Text lal = gameObject.GetComponent<Text>(); //获取到Text组件

          Debug.Log(Text+lal.text); //打印获取到组件中的text属性

}

}

--Text lal = gameObject.GetComponent<Text>()中不使用gameObject,直接经过GetComponent<Text>(),也是能够的。


++++2Transformtransform

--Transform是一个类,用来描述物体的位置,大小,选择等等信息。

--transformTransform类的对象,依附于每个物体。也是当前游戏对象的一个组件(每一个对象都会有这个组件)

++++transformgameObject

--1>两者的含义

   ---transform: 当前游戏对象的transform组件

   ---gameObject: 当前游戏对象的实例

--2>两者的联系和区别

   ---unity中每一个游戏对象都是一个gameObjectmonodevelop中的gameObject就表明着本脚本所依附的对象。 每一个gameObject都包含各类各类的组件,但从这点能够看出transformgameObject的一个组件,控制着gameObject的位置,缩放和旋转,并且每一个gemeObject都有并且必有一个transform组件。

   ---gameObject.Find()用来获取场景中那个咱们须要查找的对象(object),而transform.Find()方法则是获取当前对象的子对象下咱们须要获取的目标对象位置信息。

   ---注意:在update()中尽可能不适用find()方法,影响性能。

--3>gameObject.transformtransform.gameObject

   ---gameObject.transform,是获取当前游戏对象的transform组件。

     因此在start函数中gameObject.transformthis.transform,指向的都是同一个对象。 即:gameObject.transform == this.transform == transform

   ---transform.gameObject:获取当前transform组件所在的gameObject

     因此在start()函数中transform.gameObject == this.gameObject == gameObject

   ---因此他们能够无限的引用下去:

    gameObject.transform == this.transform == gameObject.transform.gameObject.transform == transform.gameObject.transform

       ---示例:

          public class ShowSliderValue:MonoBehavior{

              private GameObject obje;  //定义GameObject类型的指针

              private Transform trans;    //定义Transform类型指针

              void Start(){

                  Debug.Log(gameObject.name:, + gameObject.name);

                  Debug.Log(gameObject.transform.gameObject.name, + gameObject.transform.gameObject.name);

                  Debug.Log(ThisGame.name: + this.gameObject.name);

}

}

输出: gameObject.name: Label Percent

       gameObject.transform.gameObject.name: Label Percent

       ThisGame.name: Label Percent


++拓展3:《对Vector3.Lerp插值的理解》

在作游戏时会发现有些跟随动做不够圆滑或者须要一个缓冲的效果,这时,通常会考虑到插值。(好比摄像机跟随主角)

++++插值是数学上的一个概念,在这里用公式表示就是: from + (to - from)*t;这也就是Lerp的返回值(用这个公式分别算出x,y,z)。

static function Lerp(from:Vector3, to: Vector3, t:float):Vector3

  -- from 是起始位置,

  -- to 是目标位置,

  -- t fromto之间插值。

 

++++举例:

public class test:MonoBehaviour{

    Vector3 start = new Vector3(1, 1, 1);

    Vector3 end = new Vector3(2, 2, 2);

    Vector3 result;

 

    void Update(){

        result = Vector3.Lerp(start, end, 0.5f);

        Debug.log(result.ToString());

}

}

输出: (1.5, 1.5, 1.5)

 

++++看一个官方的例子:

//1秒时间动画位置移动从from开始到to结束。

public class example:MonoBehaviour{

    public Transform start;

    public Transform end;

    void Update(){

        transform.position = Vector3.Lerp(start.position, end.postion, Time.time);

}

}

位置移动从start开始到end结束,这好理解,可是为何是1秒呢?

Time.time是从0开始随时间增长的。

(上一个例子t是固定的值,返回一个固定的向量)

本例中t是变量,在不断增长。

-- Time.time=0时,transform.position = start.position,位置没有变化;

-- Time.time0趋向于1时,transform.position不断接近start.position,该脚本是挂在start物体上的,因此start会不断靠近end

-- Time.time>1的时候,会怎么样呢?(这个是不会发生的)

    ---由上面的公司 from+(to-from)*t可知,当t=1时,to-from=0,此时t就无效了。

--1是从静态角度看,例2是从动态角度看(两个变量,一个是时间在变化,一个是位置在变化)

--??2中若是不是Time.time,而是0.5,会怎么样?(只看一个变量)

   ---A物体会不断以0.5的比例无限接近于B

 

++++看一下官方第二个例子

//像弹簧同样跟随目标物体

public class example:MonoBehaviour{

    public Transform target;

    public float smooth = 5.0F;

    void Update(){

        transform.position =Vector3.Lerp(transform.position, target.position,Time.deltaTime*smooth);

    }

}


++拓展4:《摄像机跟随之Vector3.Lerp(start,end,t)方法》

++++插值是数学上的一个概念,在这里用公式表示就是: from+(to-from)*t;这也就是Lerp的返回值(用这个公式分别算出x,y,z

static function Lerp(from:Vector3, to:Vector3, t:float) :Vector3

from是起始的位置,to是目标位置,按照数字tfromto之间插值

 

using UnityEngine;

using Systme.Collections;

 

public class ThirdPersonCam:MonoBehaviour{

    public Transform follow;  //摄像机所跟随的对象

    public float distanceAway; //摄像机在水平方向与对象的距离

    public float distanceUp;  //摄像机在垂直方向与对象的距离

    public float smooth;  //过渡速度

    private Vector3 targetPosition;  //摄像机的目标速度

 

    //LateUpdate中执行摄像机操做,确保在对象的操做完成以后

    void LateUpdate(){

        //计算目标距离

        targetPosition = follow.position +Vector3.up*distanceUp - follow.forward*distanceAway;

        //对当前位置进行插值计算

        transform.position = Vector3.Lerp(transform.position, targetPosition,Time.deltaTime*smooth);

        //使摄像机观察对象

        transform.LookAt(follow);

    }

}


++拓展5:《Vector3.Lerp线性插值原理介绍》

++++向量from和向量toxy平面上,其实这并不影响讲解插值原理。

++++图中能够看出当t=0.5f时,插值向量就是中间那个向量,其x轴份量的计算图中已经给出了,y轴也同理,z轴也同样。

++++下面分析这个函数:

public static Vector3 Lerp(Vector3 a, Vector3 b, float t);

其中a就是图中的from向量,b就是to向量。

t是夹在[0 ... 1]之间,

--t=0时,返回from

--t=1时,返回to

--t=0.5,返回fromto的平均数。

   --具体实现代码以下:

/*

Summary:两个向量之间的线性插值

Param: from,向量fromto,向量tot

*/

public static Vector3D Lerp(Vector3D from, Vector3D to, float t){

    if(t < 0){

        return from;

    }else if(t >= 1){

    returnto;

    }

    returnt*to + (1-t)*from

}

++++线性插值比Slerp球形插值简单的多。


++拓展6:《deltaTime

++++deltaTime是你这一帧到下一帧经历的时间。

++++假设一秒走10帧,每帧不太稳定,间隔时间不同,用t0, t1, t2, ... t9来表示,他们知足t0 + t1 + t2 + ... + t9 = 1

++++如今你定义了一个速度V=5,意思是想要1秒走5米,如今设每帧所走的路程是s0, s2, s2, ... ,s9; 知足s0=V*t0, s1=V*t1, s2=V*t2, ..., s9=V*t9

那么看看1秒走了多少路程:S = s0 + s1 + s2 + ... + s9


++拓展7:《为什么须要Time.deltaTime》(其实就是一个补偿)

++++先说下Unity3D脚本中经常使用的两个方法:

--Update() :每帧被调用一次

--FixedUpdate :每隔Time.fixedDeltaTime被调用一次。

Time.fixedDeltaTime默认是0.02s

  (能够经过【Edit=>ProjectSettings=>Time】来设置)

--在控制游戏逻辑的过程当中,通常是须要按照每帧去处理的(使用Update()),而物理相关的处理,则须要根据时间的变化去处理(使用FixedUpdate()

++++当咱们在Update()中,但愿经过每隔一段时间去执行一些逻辑(好比最多见的修改GameObjectTransform),就须要使用Time.deltaTime来达到效果了。

-- 根本缘由,就是帧率在不断变化,Update()被调用的时间并非线性的。

  |Frame_1     |Frame_2   |Frame_3          |Frame_4    |Frame_5  |

-- 若是咱们但愿使GameObject每隔一段时间沿X轴正方向移动1个单位,能够在FixedUpdate()中这样写:

   transform.Translate(Vector3.right);

-- 若是但愿经过Update()来实现,把这句写到Update()中是不合适的,你会看到GameObject移动起来出现卡段。解决方法,是给移动的距离乘以Time.deltaTime:

   transform.Translate(Vector3.right * Time.deltaTime);

-- 为何乘以Time.deltaTime以后就行了呢?

  ---TransformTranslate方法接受的参数,其实是一个惟一,而不是速度。

  ---FixedUpdate()的调用间接是: 0.02s=t1=t2=t3=t4,全部实际上,位移=速度*时间,transform.Translate(Vector3.right) ==>transform.Translate(Vector3.right*1)

    ----1就表明了单位时间Time.fixedDeltaTime

  ---由于Update()并非按照单位时间被调用的,因此要乘以每次的“帧间时间”,而这个时间就是Time.deltaTime。(这样的操做至关于一个“补偿”,将每次帧率的变化,经过时间的变化同步体现到执行逻辑上。)

++++还有一个问题,就是乘以Time.deltaTime以后速度变慢。

--其实很好解决,在FixedUpdate()中,咱们每次的执行间隔是0.02s,而单位时间体现的是1;一样咱们在Update()中,执行间隔是Time.deltaTime,为了与FixedUpdate一致,时间单位也须要是1

  ---因此直接乘以FixedUpdate中真实时间和单位时间的比例:(1/0.02=50)便可,让Update中的时间也变成单位时间。

++++Update()中须要依赖固定时间去执行的逻辑,均可以经过Time.deltaTime来进行“补偿”。道理是同样的。


++拓展8:《四元数(Quaternion)和旋转》

++++旋转,应该是三种坐标变换:缩放、旋转和平移,中最复杂的一种了。

++++有一种旋转的表示方法叫四元数。(咱们熟悉的另外两种旋转和表示方法:矩阵旋转和欧拉旋转。)

++++四元数本质上是一种高阶复数,是一个四维空间,相对于复数的二维空间。(复数由实部和虚部组成,即x=a+bii是虚数部分)

++++Unity里,transform组件有一个变量名为rotation,它的类型就是四元数。(实际上,四元数的x,y,zR的三个值从直观上来说没什么关系,固然会存在一个表达式能够转换)

++++三种旋转方式(矩阵旋转、欧拉旋转、四元数旋转)的优缺点:

--矩阵旋转

  ---优势:

    ----旋转轴能够是任意向量;

  ---缺点:

    ----旋转其实只须要知道一个向量+一个角度,一共4个值的信息,但矩阵法却使用了16个元素。

    ----并且在作乘法操做时也会增长计算量,形成了空间和时间上的一些浪费。

--欧拉旋转

  ---优势:

    ----很容易理解,形象直观;

    ----表示更方便,只须要3个值(分别对应x,y,z轴的旋转角度);(?它仍是转换到了33*3的矩阵作变换,效率不如四元数)

  ---缺点:

    ----要按照一个固定的坐标轴的顺序旋转的,所以不一样的顺序会形成不一样的结果;

    ----会形成万向节锁(Gimbal Lock)的现象。这种现象的发生就是因为上述固定坐标轴旋转顺序形成的。理论上,欧拉旋转能够靠这种顺序让一个物体指到任何一个想要的方向,但若是在旋转中不幸让某些坐标轴重合了就会发生万向节锁,这时就会丢失一个方向上的旋转能力,也就是说在这种状态下咱们不管怎么旋转(固然仍是要原先的顺序)都不可能获得某些想要的旋转效果,除非咱们打破原先的旋转顺序或者同时旋转3个坐标轴。

    ----因为万向节锁的存在,欧拉旋转没法实现球面平滑插值;

--四元数旋转

  ---优势:

    ----能够避免万向节锁现象;

    ----只须要一个4维的四元数就能够执行绕任意过原点的向量的旋转,方便快捷,在某些实现下比旋转矩阵效率更高;

    ----能够提供平滑插值;

   ---缺点:

     ----比欧拉旋转稍微复杂了一点点,由于多了一个维度;

     ----理解更困难,不直观。


++拓展9:《unity用点乘和叉乘来判断物体与人物的相对位置》

++++用点乘来判断物体是在人物的前方,仍是后方。

++++用叉乘来判断是在人物的左手边,仍是右手边。

 

++++示例代码

using UnityEngine;

using System.Collections;

using UnityEngine.UI;

 

public class NewBehaviourScript : MonoBehaviour{

    public Text textA;

    public Text textB;

    public Text textLR;

    public Text textFB;

    public GameObject targetGameObject;

 

    void Start(){

    }

 

    //Update is called once per frame

    void Update(){

    }

 

    void OnGUI(){

        Vector3 vectorTarget = targetGameObject.transform.position - transform.position;

        vectorTarget = new Vector3(vectorTarget.x, 0, vectorTarget.z);

        Vector3 vectorForward = transform.forward;

        float dotValue = Vector3.Dot(vectorForward.normalized, vectorTarget.normalized);

        float angle = Mathf.Acos(dotValue)*Mathf.Rad2Deg;

        textA.text =angle: + angle + dotValue: + dotValue;

 

        Vector3 crossValue = Vector3.Cross(vectorForward, vectorTarge);

        textB.text =crossValue: + crossValue;

 

        if(crossValue.y > 0){

            textLR.text =;

        }else{

            textLR.text =;

        }

 

        if(dotValue > 0){

            textFB.text =;

        }else{

            textFB.text =;

        }

    }

 

    public Slider slider;

    public void ownAngleChange(){

        float angle = slider.value;

        transform.rotation = Quaternion.Euler(0, angle, 0);

    }

}



##四、预设体

++4.1、预设体相关概念

++++预设体是一个游戏对象及其组件的集合,目的是使游戏对象及资源可以被重复使用,相同的游戏对象能够经过一个预设体来建立,此过程能够理解为实例化。

++++把一个游戏对象从层级视窗拖到工程视窗后就会生成一个预设体。


++4.2、预设体实例化

++++把预设体直接拖到层级视窗上,就会实例化一个游戏对象。

++++对预设体作出修改后,其所实例化的对象也会作出相应的改动。


++++Prefab】经过预设体建立的游戏对象会在Inspector视窗出现Prefab

++++Select】点击Select能够选中建立该物体的预设体。

++++Revert】更改实例化后的游戏物体,点击Revert,会取消更改。

++++Apply】将该对象的信息同步到预设体,使用该预设体实例化的其余游戏对象也随之改变。

++++预设体的使用:

    static Object Instantiate(Object original, Vector3 position, Quaternion rotation);


++拓展11:《多种移动方式参考》

++++1transform.position

transform.position += Vector3.forward * Time.deltaTime * 5;

 

++++2Translate:

    transform.Translate(Vector3.forward * 5 * Time.deltaTime, target.transform);

 

++++3Lerp:

    transform.position = Vector3.Lerp(transform.position, target.position, 0.5f*Time.deltaTime);

 

++++4、获取输入设备的横轴、纵轴:

float hor = Input.GetAxis(Horizontal);

float var = Input.GetAxis(Vertical);

transform.position += new Vector3(hor, 0, ver) * Time.deltaTime * 5f;


++++5、刚体:

float hor = Input.GetAxis(Horizontal);

float ver = Input.GetAxis(Vertical);

rig.AddForce(new Vector3(hor, 0, ver) * 5f * Time.deltaTime);


++++6Vector3.MoveTowards();

transform.position = Vector3.MoveTowards(transform.position, target.position, 5f * Time.deltaTime);

 

++++7SmoothDamp();

Mathf.SmootDamp();

//角色控制器;




#立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

++立钻哥哥推荐的拓展学习连接(Link_Url

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/

++++Unity引擎基础http://www.noobyard.com/article/p-ggcuedyq-ka.html

++++Unity面向组件开发http://www.noobyard.com/article/p-eiunlkzw-dt.html

++++Unity物理系统http://www.noobyard.com/article/p-mcqnwufb-kd.html

++++Unity2D平台开发http://www.noobyard.com/article/p-brjbvtac-hs.html

++++UGUI基础http://www.noobyard.com/article/p-nvzrvath-mc.html

++++UGUI进阶http://www.noobyard.com/article/p-tpspjolu-gt.html

++++UGUI综合http://www.noobyard.com/article/p-nfgrebqx-gg.html

++++Unity动画系统基础http://www.noobyard.com/article/p-otjpnbzz-dq.html

++++Unity动画系统进阶http://www.noobyard.com/article/p-hxghrtgb-bp.html

++++Navigation导航系统http://www.noobyard.com/article/p-skpvrobt-t.html

++++Unity特效渲染http://www.noobyard.com/article/p-sudpqrhk-bp.html

++++Unity数据存储http://www.noobyard.com/article/p-ybvcceul-m.html

++++Unity中Sqlite数据库http://www.noobyard.com/article/p-vxpuqxev-ca.html

++++WWW类和协程http://www.noobyard.com/article/p-alggjlwu-cy.html

++++Unity网络http://www.noobyard.com/article/p-bjvfgzwg-dw.html

++++C#事件http://www.noobyard.com/article/p-dietpjzv-gm.html

++++C#委托http://www.noobyard.com/article/p-oiohmxtc-gh.html

++++C#集合http://www.noobyard.com/article/p-vdfpislb-ex.html

++++C#泛型http://www.noobyard.com/article/p-vujvnprk-ee.html

++++C#接口http://www.noobyard.com/article/p-emexlwmu-dm.html

++++C#静态类https://blog.csdn.net/vrunsoftyanlz/article/details/78630979

++++C#中System.String类http://www.noobyard.com/article/p-uchiaxzw-cq.html

++++C#数据类型http://www.noobyard.com/article/p-kqtbvoyq-ba.html

++++Unity3D默认的快捷键http://www.noobyard.com/article/p-gbllyjbs-s.html

++++游戏相关缩写http://www.noobyard.com/article/p-pzpxsztf-gm.html

++++设计模式简单整理http://www.noobyard.com/article/p-scmbzocc-hg.html

++++U3D小项目参考https://blog.csdn.net/vrunsoftyanlz/article/details/80141811

++++UML类图http://www.noobyard.com/article/p-aakurcwi-bm.html

++++Unity知识点0001http://www.noobyard.com/article/p-bqmetnys-ep.html

++++U3D_Shader编程(第一篇:快速入门篇)http://www.noobyard.com/article/p-ptwlpwbc-gz.html

++++U3D_Shader编程(第二篇:基础夯实篇)http://www.noobyard.com/article/p-dadqpvvp-hv.html

++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/


--_--VRunSoft : lovezuanzuan--_--