Unity学习草稿

来源:互联网 发布:蜂窝数据打不开 编辑:程序博客网 时间:2024/06/06 13:15

预设体

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

要区分 预设体 与 预设体游戏对象!!!

在create栏把游戏对象拖到project栏即可创建预设体
预设体扩展名为.prefab

然后就可以把预设体拖到场景中创建预设体游戏对象

对预设体游戏对象可以单个的修改

//常用
用脚本在游戏时动态创建创建预设体游戏对象
先在create创建一个空gameobject
为此对象添加脚本:
public Gameobject playerPrefab;用来记录需要作为预设体的对象


fun里:
Instantiate(playerPrefab);//但是这种方法无法控制创建的位置


Vector3 pos = new Vector3();
pos.y = 0.5f;//让对象在地面之上
pos.x = Random.Range(-5f,5f);//使用随机数 -5.0~5.0之间
pos.z = Random.Range(-5f,5f);


float angel = Random.Range(0f,360f);//角度随机


Instantiate(playerPrefab,pos,Quatenion.AngelAxis(angel,Vector.up));
预设体   位置   角度
创建一个对象在pos位置,旋转角度为正y轴angel度
Instantiate返回值为Object,可以用转换为gameobject:
Gameobject g = Instantiate(...) as Gameobject;

p.AddComponent<TestSP>();//为其添加脚本


Class Inptu
用于获取用户事件,如按键、鼠标

一般写在Update里
每帧监听用户事件

if(Input.GetKeyDown(KeyCode.W));
当用户按下W时返回true,否则返回false,KeyCode.W是枚举
因为是在Update中,所以是每帧检查用户是否按下W
if(Input.GetKeyUp(KeyCode.Alpha1));
按下并松开 1 时
if(Input.GetKey(KeyCode.Q));
持续按下按钮时持续触发

但是应该使用:
if(Input.GetButton("Jump"))...

Input.GetMouseButtonDown(0);
参数0监听鼠标左键按下,1监听鼠标右键
同理GetMouseButtonUp与GetMouseButton对应GetKeyUp与GetKey

Input.GetMouseButton(0);单击鼠标左键,1为右键 2...

获取某个坐标轴上的一个方向
float h = Input.GetAxis("Horizontal");//当按下a时返回-1,d返回1
float v = Input.GetAxis("Vertical");//w、s同上



射线

虚拟射线能够检测所有碰撞到的物体
使用Physics类的Raycast方法实现射线碰撞检测功能

Vector3 target;//目标点
bool isOverMove=true;//是否到达目标
RaycastHit hitinfo = new RaycastHit();

punlic float speed;//速度

void Update(){
if(Input.GetMouseButtonDown(0)){
//创建一条从摄像机开始经过鼠标当前位置的射线
Ray ray = Camera.main.ScreenPoingToRay(Input.GetMousePosition);
//发射射线 是否发射碰撞 
if(Physics.Raycast(ray,out hitinfo)){//保存碰撞点信息到hitinfo
//Physics.RaycastAll()会返回射线经过的所有游戏对象
if(hitinfo.collider.name = "Plane"){//是否与地面发生碰撞
target=hitinfo;
target.y=0.5f;//因为碰撞点是地面,所以y为0
isOverMove=false;
}
}
}
//移动对象
MoveTo(target);
}

void MoveTo(Vector3 target){//移动
if(!isOverMove){
Vector3 v1 = tar - transform.position;//计算距离
transform.position+=v1.Normalized*speed*Time.deltaTime;
//单位方向*  速度大小*  时间
//每秒单位向v1方向移动速度*每帧时间

if(Vector3.Distance(tar,transform.position)<=0.1f){
//Distance返回float,求两个点的距离是否<=0.1f
isOverMove=true;
transform.position=tar;
}
}
}



物理材质

物理材质能够给物体添加摩擦力和弹力
物理材质只能添加到带有Collider组件的对象上
在带有Collider组件的对象上的Material可以指定游戏对象的物理材质

可以在project视图创建一个物理材质Physical Material
可以直接拖到游戏对象

在选中物理材质时,右边Inspector视图中:
Dynamic Friction:0.6 滑动摩擦力取值范围0~正无穷
Static Friction:0.6 静摩擦力0~正无穷 
Bounciness:0 弹力
Friction Combine:平均值/最小值/乘积/最大值
表示两个物体相碰撞时弹力的结合计算



碰撞与事件触发

发生碰撞的两个物体必须都带有Collider
发生碰撞的两个物体至少有一个带有Rigidbody
发生碰撞的两个物体必须有相对运动

碰撞先关的事件有3个:
1、每次对象与对象碰撞时调用一次
void OnCollisionEnter(Collision other){//与拥有Collider的对象碰撞时调用
print(gameObject.name+"与"+other.gameObject.name+"开始发生碰撞");
}
2、对象与对象碰撞后黏在一起受力的作用运动时持续调用
void OnCollisionStay(Collision other){//持续碰撞时持续调用
print(gameObject.name+"与"+other.gameObject.name+"持续发生碰撞");
}
3、每次对象与对象碰撞后并离开时调用一次
void OnCollisionExit(Collision other){//碰撞结束时调用
print(gameObject.name+"与"+other.gameObject.name+"结束发生碰撞");
}



形状Colliser组件 碰撞器

形状碰撞器
不同形状的碰撞检测
当Colliser不启用时不会发生碰撞,会直接穿过

Colliser:
Is Trigger:false 是否触发器
Material:None 物理材质
Center:0 0 0 物体碰撞检测的形状的位置
Size:0 0 0 物体碰撞检测形状大小

当勾选Is Trigger时,有3个触发器相关事件:
1、每次刚进入触发器范围时调用一次
void OnTriggerEnter(Collider other){
print("对象"+other.gameObject.name+"进入范围"+gameObject.name);
}
2、进入触发器后持续待在触发范围时持续调用
void OnTiggerStay(Collider other){
print("对象"+other.gameObject.name+"持续触发"+gameObject.name);
}
3、每次进入并离开触发范围时调用
void OnTiggerExit(Collider other){
print("对象"+other.gameObject.name+"离开范围"+gameObject.name);
}



Rigidbody组件

能够模拟真实的物理效果
Unity中使用的是NVIDA的PhysX物理引擎

在Unity中使用Rigidbody组件让游戏对象受物理引擎的控制

组件参数(默认):
Mass(质量):1 决定物品的惯性
Drag(空气阻力):0 下落速度,与摩擦力无关
Angular Drag(角速力):0.05 物体旋转阻力
Use Cravity:true 是否受重力影响
is Kinematic:false 运动学,为true时不会受到重力影响,
Interpolate:None 差值:内差值/外差值当对象抖动时可以试试使用,计算物体上下一针的位置
Collision Detection(碰撞检测):Discrete(离散碰撞检测,一般使用) 快速运动的物品使用Continuous,相碰撞的物体都是高速运动物体时使用Continuous Dynamic
Constraints(约束)
Freeze Position冻结某个轴受到力的影响时的位移
Freeze Rotation冻结某个轴受到力的影响时的旋转

Sp:
先获取组件
Rigidbody r;
void Start(){
r=GetComponent<Rigidbody>();
}

调用
void Update(){
if(Input.GetKey(KeyCoude.Alpha1)){//检测按1
//r.AddForce(new Vector3(0f,10f,0f));//给物品施加一个y为10f的力

//r.AddTorque(new Vector3(0f,10f,0f));//给游戏对象施加力矩/扭矩,扭矩可以使物体旋转

//r.AddForceAtPosition(new Vector3(0f,10f,0f),new Vector3(0.5f,0.5f,0.5f));//给游戏对象在指定位置添加一个力
r.AddExplosionForce(1500f,Vector3.zero,4f);//在场景0,0,0位置创建一个1500f的爆炸力,范围是4f
}
}





鼠标事件


void OnMouseDown()//鼠标在游戏对象上按下时
void OnMouseUp()//鼠标在游戏对象按下,松开时(松开可以不在对象内)
void OnMouseDrag()//鼠标在游戏对象持续按下时持续调用(按下时移出对象还是会持续触发)

void OnMouseEnter()//鼠标进入游戏对象时(与对象接触)
void OnMouseExit()//鼠标离开时.....
void OnMouseOver()//鼠标持续停留在游戏对象上时持续调用

void OnMouseUpAsButton()//鼠标在游戏对象上按下并松开时(与OnMouseUp类似,像按钮一样)


vector3

//Vector3就是一个类,表示向量(既有大小又有方向的量)
Vector3 v = new Vector3();
//xzy分别是3个方向的分量
float x=v.x;
float y=v.y;
float z=v.z;

//获取v的单位向量
v.Normalize();//v的长度会变为1,单方向不变
Vector3 vn = v.normalized();//返回v方向上的单位向量,但v本身方向不会变化

//获取v的长度
float l = v.magnitude; get

Vector3.up;静态成员 get;表示世界坐标系中Y轴正方向上的单位向量
//(0 1 0)xyz
Vector3.down;静态成员 get;表示世界坐标系中Y轴负方向上的单位向量
//(0 -1 0)xyz
Vector3.right;静态成员 get;表示世界坐标系中X轴正方向上的单位向量
//(1 0 0)xyz
Vector3.left;静态成员 get;表示世界坐标系中X轴负方向上的单位向量
//(-1 0 0)xyz
Vector3.forward;静态成员 get;表示世界坐标系中z轴正方向上的单位向量
//(0 0 1)xyz
Vector3.forward;静态成员 get;表示世界坐标系中z轴负方向上的单位向量
//(0 0 -1)xyz
Vector3.zero;表示原点(0 0 0)
//(0 0 0)

//求两个向量的夹角
float angel = Vector3.Angel(v1,v2)

//获取两个点的距离
Vector3 pos1 = new Vector3(4f,2f,11f);
Vector3 pos2 = new Vector3(2f,13.6f,8f);
float d = Vector3.Distance(pos1,pos2);

//向量点乘
float dd = Vector3.Dot(v1,v2);

//向量叉乘
Vector3 vc = Vector3.Cross(v1,v2);





常用函数

UNITY常见的反射调用事件

void Awake()
在Awake中做一些初始化操作(主要对public成员)
每当脚本被加载时调用,哪怕脚本没有运行、激活(没有被勾上)
每次dome运行的生命周期只会调用一次

void OnEnable()
在每次激活脚本时都会调用(比如打上勾)

void Start()
在Awake中做一些初始化操作
在第一次调用Update之前调用
每次dome运行的生命周期只会调用一次

void FixedUpdate()
以固定的频率调用
不受图像刷新帧速率的影响
一般把处理物理的代码放在这里

void Update()
每帧调用一次Update
(硬件设备条件为准)

void LateUpdate()
在Update调用完之后再调用

void OnGUI()
持续调用,频率高
IMGUI代码需要写在OnGUI中
现在不常用

void OnDisable()
取消激活状态后调用

void OnDestroy()
检查到对象销毁时调用
只会调用一次




clas Time

Time类中封装了常用的时间控制方法

Time进行时间控制
Time.time;//float 从游戏运行开始到当前帧的总时长 单位秒
print(Time.time);

Time.deltaTime;//float 从上一帧开始到当前帧结束的这两帧之间的间隔 单位秒 get
print(Time.deltaTime);
void Update(){
//让游戏对象每秒旋转30°,不依赖于刷新帧率
trans.form.Rotate(Vector3.up,Time.deltaTime*30f);
}

Time.timeScale;//表示时间流逝的快慢
//1为正常时间流逝,同理2 3为N倍的时间流逝
//0为时间停止,游戏暂停



class Mathf

Mathf类中封装了常用的数学方法

Mathf.Abs(-12);//int 求绝对值
Mathf.Max\Min(a,b,c,d,e);//int 求最大最小值
Mathf.Sin(30f);//float 正弦
Mathf.Cos(30f);//float 余弦
Mathf.PI;//圆的π 静态
Mathf.Sqrt(4);//int 求平方根
...



transform组件

控制gameObject的位置、旋转、缩放
管理游戏对象的父子关系

获取当前脚本所挂载的游戏对象身上的Transform组件
transform //继承MonoBehaviour所拥有的

print(transform.position);//输出游戏对象的位置
//(0 0 0)xyz
if(Input.GetKeyDown(KeyCode.P))//检测P键按下
{ //position世界坐标系位置
transfor.position=new Vector3(0 0 0);//设置游戏对象位置为0 0 0
//或=Vector3.zero;(0 0 0)
}

子对象的position的0 0 0为父对象的坐标点
transform.localPosition;//局部坐标系中的位置
//注:当前脚本在子对象上
if(Input....(KeyCode.P))
{
transfor.localPosition=Vector3.zero;
//子对象的坐标为父对象的坐标
}

控制游戏对象的缩放
transfor.localScale;
transfor.localScale=new Vector3(1f,2f,1f);//缩放为1x2y1z的2倍y轴
http://wpa.qq.com/msgrd?v=3&uin=3390397209&site=qq&menu=yes

让游戏对象进行移动
transfor.Translate(new Vector3(0,1,0));让对象的xyz增加0 1 0(累计加)

让游戏对象旋转
transfor.Rotate(Vector3.up,10f);围绕y轴正方向旋转10°

transfor.eulerAngles=new Vector3(0f,45f,0f);//设置对象的y轴旋转为45度 欧拉角属性

transfor.rotation;//世界坐标系旋转,一般不直接修改四元数
transfor.localRotation;//局部坐标系旋转,一般不直接修改四元数

控制游戏对象的父子关系
transform.parent;//获取当前父对象的transform组件
transform.root;//获取根对象 get
transform.Find("Cube");//通过游戏对象名字查找子对象返回transform
transform.FindChild("Cube");//效果同上,返回第一个符合的




GameObject

在场景中的每个对象都是gameobject
每个gameobject都有一个transform组件
游戏对象的功能由组件组成

tag标签
layer层

脚本类继承MonoBehaviour类
MonoBehaviour类有gameObject类对象
gameObject代表当前游戏对象本身(相当于c++的this)
在属性视图中可见的属性都可以用gameObject进行修改:
gameObject.name="lisa";代表游戏对象的名字 set get
print(gameObject.name);

gameObject.tag="Player";代表属性上的tag set get
print(gameObject.tag);

print(gameObject.activeSelf);获取游戏对象的激活状态get

gameObject.SetActive(true);游戏对象的激活状态 fun

在脚本类中,public的变量对象:
如 public string myname="233";
那么可以在属性面板直接修改,因为是public的

当一个gameObject带有多个脚本组件时
可以获取到同一GameObject的其他组件:
Test c = gameObject.GetComponent<Test>();需要指定类型
print(c.myname);

为该游戏对象添加指定类型的组件
gameObject.AddComponent<Light>();为该游戏对象添加一个Light(灯光)组件

在场景中可通过Tag值查找游戏对象,GameObject.fingameObjectWithTag("Player");查找Tag为Player的一个游戏对象:
GameObject g = GameObject.fingameObjectWithTag("Player");
GameObject[] gs=GameObject.FindGameObjectsWithTag("player");
//查找所有Palyer的对象
或者用GameObject.FindWithTag("Plaer")进行查找

通过游戏对象名查找游戏对象:
GameObject.Find("Main Camera");查找摄像机对象

游戏对象的销毁:
GameObject.Destory();
GameObject.Destory(gameObject,2f);让this在2s后销毁







print与Debug.Log
只能在继承monobehaviour的类中使用print()
其他情况只能使用Debug.Log()












0 0
原创粉丝点击