Unity3D游戏开发笔记1.docx

上传人:b****7 文档编号:9016113 上传时间:2023-02-02 格式:DOCX 页数:16 大小:150.97KB
下载 相关 举报
Unity3D游戏开发笔记1.docx_第1页
第1页 / 共16页
Unity3D游戏开发笔记1.docx_第2页
第2页 / 共16页
Unity3D游戏开发笔记1.docx_第3页
第3页 / 共16页
Unity3D游戏开发笔记1.docx_第4页
第4页 / 共16页
Unity3D游戏开发笔记1.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

Unity3D游戏开发笔记1.docx

《Unity3D游戏开发笔记1.docx》由会员分享,可在线阅读,更多相关《Unity3D游戏开发笔记1.docx(16页珍藏版)》请在冰豆网上搜索。

Unity3D游戏开发笔记1.docx

Unity3D游戏开发笔记1

Unity3D游戏开发笔记

1.【角色移动】

首先打开Unity3d,并创建一个新的工程,然后我导入了所用到包:

场景,角色模型,以及DaikonGUI(现在重新做游戏的话,GUI就不用系统自带的了,这里改用DaikonGUI)的包。

然后新建了_Scene、_GUI和_Player三个文件夹,并将刚开始导入的资源包移动进去,以便后来区分。

如图:

接下来在场景中建立一块地形,并将其大小设置为100*100:

接下来就可以使用导入的场景资源包进行地形的描绘了。

不过,这里我先不进行地形之类的具体创建,毕竟这都是细节,目前应该先解决角色控制方面的问题,如图,先将先前导入的角色模型拖入场景中:

初一看来,是不是好像人物的比例有些不对,似乎太小了些?

所以可以在角色旁边随便创建一个立方体,比较一下:

这个确实大了些,于是对比着场景中的角色,在Inspector面板中进行调整,比例大概在0.15的样子刚好合适:

觉得差不多了,就可以选中导入人物的所有模型,并将ScaleFactror都设置为0.15。

将一同导入的有动画的模型比例也设置为0.15是必须的,因为如果忘记设置动画模型比例的话,播放动画就会造成人物变形。

接下来创建一个新文件夹,并将名字重命名为_Script,这里将存放接下来游戏中所用到的所有脚本。

最开始当然是创建一个控制人物的脚本啦,那么现在就在_Script文件夹下创建一个C#脚本,就命名为“PlayerControl”吧。

然后双击脚本文件进入Mono编辑器中,系统已经默认生成了一些代码,删除不必要的注释后,在代码最开始分别添加上人物的各个属性,这些一开始就可以定义好:

usingUnityEngine;

usingSystem.Collections;

//泰课在线

publicclassPlayerControl:

MonoBehaviour{

#region人物属性

publicstringm_name="CWH";//名字,以后看可以让玩家自己取名字的

publicintm_experience=0;//这是经验,将会是隐性的属性,也就是说在玩家眼中是不可见的。

原来的版本没有,这次重新做的话,还是决定加进去。

publicintm_maxLife=100;//生命

publicintm_currentLife=100;//当前生命

publicintm_maxMagic=50;//魔法值

publicintm_currentMagic=50;//当前魔法值

publicintm_defense=10;//防御力

publicintm_attack=20;//攻击力

publicintm_speed=3;//速度

publicintm_rotateSpeed=180;//旋转速度

#endregion

#region对象

publicTransformm_transform;//定义一个自己的对象,据说有好处。

privateCharacterControllerm_controller;//定义角色控制器

#endregion

voidStart()

{

m_transform=this.transform;

m_controller=GetComponent();

}

voidUpdate()

{

}

}

然后在最下方添加一个Move函数,以作为对角色的移动等的控制:

voidMove()

{

if(Input.GetKey(KeyCode.A))//以键盘上的A键控制角色向左旋转,注意向左旋转的话,rotateSpeed是为负的。

{

m_transform.Rotate(m_transform.up*-m_rotateSpeed*Time.deltaTime);

}elseif(Input.GetKey(KeyCode.D))//以键盘上的D键控制人物向右旋转

{

m_transform.Rotate(m_transform.up*m_rotateSpeed*Time.deltaTime);

}

}

这次我准备使用CharactorController控制角色,旋转的方式写完了,那么移动的方式该怎么判断呢?

毕竟角色必须能够前后移动才行。

于是想想可以定义一个中间变量,按W键为前,将其置为1,按S键位后,将其置为-1,然后在使用CharactorController中的SimpleMove函数时(使用角色控制器的话,只能使用其自带的SimpleMove或Move函数进行移动,否则无法产生碰撞,当初在这一点上折腾了好久才明白过来......),可以用速度乘以这个中间变量,那么最后的移动不就可以分前后了么?

所以就在最前面紧接着”对象“后面,定义一堆存放变量的地方,并将移动方向m_moveDirection变量定义好:

#region变量

privateintm_moveDirection=-1;//这个是属于临时变量,用于判断移动方向的

#endregion

然后在Move函数中定义一个Vector3来存储向前移动的方向:

Vector3m_forward=m_transform.TransformDirection(Vector3.forward);

在Move函数中加入按下W键和S对移动方向的判断后,在最后使用SimpleMove函数就可以控制角色的移动了。

这样,将这个脚本赋给场景中的角色,并为角色添加一个角色控制器以后,按下W间就可以向前移动,按下S键就会向后移动。

不过,运行后很快就可以发现,角色往前或者往后移动动之后,就不会停下来了?

因为在最后使用SimpleMove移动的时候,没有把移动速度归0,所以一旦开始移动后,速度会始终保持,就停不下来了。

这时就可以再定义一个临时变量m_moveSpeed作为移动时的速度,默认值为0,在S键和W键判断下时,分别计算m_moveSpeed的值,如果两个键都没有按下,那么就将它的值置为0,在最后的SimpleMove中再根据这个去进行移动:

if(Input.GetKey(KeyCode.W))//向前移动

{

m_moveDirection=1;

m_moveSpeed=m_moveDirection*m_speed;

}elseif(Input.GetKey(KeyCode.S))//向后移动

{

m_moveDirection=-1;

m_moveSpeed=m_moveDirection*m_speed;

}elsem_moveSpeed=0;

m_controller.SimpleMove(m_forward*m_moveSpeed);//移动

这样的话,移动就差不多正常了,不过角色移动起来硬邦邦的,因为现在没有任何动画。

下一次就加上动画罢。

而现在,则先新建一个_Map文件夹以存放场景文件,Ctrl+S保存当前场景到_Map文件夹下,并命名为“First”,代表第一个场景。

 

以下是这次PlayerControl脚本的所有代码:

usingUnityEngine;

usingSystem.Collections;

publicclassPlayerControl:

MonoBehaviour{

#region人物属性

publicstringm_name="CWH";//名字,以后看可以让玩家自己取名字的

publicintm_experience=0;//这是经验,将会是隐性的属性,也就是说在玩家眼中是不可见的。

原来的版本没有,这次重新做的话,还是决定加进去。

publicintm_maxLife=100;//生命

publicintm_currentLife=100;//当前生命

publicintm_maxMagic=50;//魔法值

publicintm_currentMagic=50;//当前魔法值

publicintm_defense=10;//防御力

publicintm_attack=20;//攻击力

publicfloatm_speed=3;//速度

publicintm_rotateSpeed=180;//旋转速度

#endregion

#region对象

publicTransformm_transform;//定义一个自己的对象,据说有好处。

privateCharacterControllerm_controller;

#endregion

#region变量

privateintm_moveDirection=-1;//这个是属于临时变量,用于判断移动方向的

privatefloatm_moveSpeed=0;//这个是临时的速度变量,用于判断移动速度具体方向

#endregion

voidStart()

{

m_transform=this.transform;

m_controller=GetComponent();

}

voidUpdate()

{

Move();

}

voidMove()

{

Vector3m_forward=m_transform.TransformDirection(Vector3.forward);

if(Input.GetKey(KeyCode.A))//以键盘上的A键控制角色向左旋转,注意向左旋转的话,rotateSpeed是为负的。

{

m_transform.Rotate(m_transform.up*-m_rotateSpeed*Time.deltaTime);

}elseif(Input.GetKey(KeyCode.D))//以键盘上的D键控制人物向右旋转

{

m_transform.Rotate(m_transform.up*m_rotateSpeed*Time.deltaTime);

}elseif(Input.GetKey(KeyCode.W))//向前移动

{

m_moveDirection=1;

m_moveSpeed=m_moveDirection*m_speed;

}elseif(Input.GetKey(KeyCode.S))//向后移动

{

m_moveDirection=-1;

m_moveSpeed=m_moveDirection*m_speed;

}elsem_moveSpeed=0;

m_controller.SimpleMove(m_forward*m_moveSpeed);//移动

}

}

2014.1.18

2.【人物动画、相机控制及昼夜系统】

这次先把动画搞定吧。

首先,默认状态下是Idle的动画,这个可以现在人物的Inspector中设置好Animation默认播放,然后可以在昨天脚本中的Move函数中,W、A、S、D四个键控制移动的判断语句中加入播放动画的控制语句,不过在这之前,还必须在脚本开始处定义一个Aniamtion组件:

publicAnimationm_animation;

并在Start函数中获得该组件:

m_animation=GetComponent();

然后就可以在W、A、S、D四个控制角色移动的if语句下加上m_animation.CrossFade("Run");这个播放动画的函数了,表示人物移动的时候会播放“跑”的动画。

不过跑这个动画只需要在人物移动时播放就可以了,所以在下面的判断移动的if语句后面,还要改一下,改成elseif进行判断:

elseif(m_animation.IsPlaying("Run"))//如果没有移动,就让角色闲着

{

m_moveSpeed=0;

m_animation.CrossFade("Idle");

}

意思是说,如果当前角色没有做任何移动的话,那么就播放默认的Idle动画。

好了,现在角色的移动就差不多了!

不过,在ARPG中,角色还得会跳才行,这里我就设定为按下空格键跳起来,所以还要在最前面加上一个跳跃力的属性:

publicfloatm_jump=45;//跳跃力

然后在Move函数中,添加这样一个判断:

if(m_controller.isGrounded)//只有在地面才可以跳

{

if(Input.GetKey(KeyCode.Space))

{

m_animation.CrossFade("Jump2");

m_transform.Translate(Vector3.up*m_jump*Time.deltaTime);

}

}

首先判断角色是否在地面,在地面的同时按下空格键才可以跳起来,并播放跳起来的动画。

这样的话,人物的移动以及动画就差不多完成了,接下来是相机。

在游戏中,还必须保证相机始终跟随角色,他就相当于玩家在游戏世界中的眼睛(大家都是这样认为的),所以接下来就是对相机的控制。

首先在_Script文件夹下新建一个脚本,并命名为MyCamera,双击在编辑器中打开,并定义好如下几个变量:

privatefloatm_distanceAway=4.5f;

privatefloatm_distanceUp=1.5f;

privatefloatm_smooth=5;

publicTransformm_player;//玩家对象

privateTransformm_transsform;//自己

分别代表相机距离玩家的距离、高度、移动的平滑度,以及玩家对象和自己的对象。

然后在Start中可以分别获取两个对象:

m_transsform=this.transform;

_player=GameObject.FindGameObjectWithTag("Player").transform;

相机除了跟随角色的功能外,还有最大的一个问题就是喜欢“穿墙”,碰到这个问题的不再少数,网上的解决方案基本上也很难找着。

这个问题也困惑了我很久,不过最终在MOMO研究院看见了一片博文(这里还是感谢下雨松大大),参考他的相机控制部分代码,相机终于正常了!

以下都是放在Update函数中的:

floatm_wangtedRotationAngle=m_player.transform.eulerAngles.y;//取得相机应当旋转的角度

floatm_wangtedHeight=m_player.transform.position.y+m_distanceUp;//获取相机应该移动的高度

floatm_currentRotationAngle=m_transsform.eulerAngles.y;//获得相机当前角度

floatm_currentHeight=m_transsform.position.y;//获得相机当前的高度

m_currentRotationAngle=Mathf.LerpAngle(m_currentRotationAngle,m_wangtedRotationAngle,m_smooth*Time.deltaTime);//在一定时间内将当前角度更改为角色面对的角度

m_currentHeight=Mathf.Lerp(m_currentHeight,m_wangtedHeight,m_smooth*Time.deltaTime);//更改当前高度

Quaternionm_currentRotation=Quaternion.Euler(0,m_currentRotationAngle,0);//返回一个绕y轴旋转玩家当前角度那么多的度数

Vector3m_position=m_player.transform.position;//玩家的位置

m_position-=m_currentRotation*Vector3.forward*m_distanceAway;//相机位置差不多计算出来了

m_position=newVector3(m_position.x,m_currentHeight,m_position.z);//将相机应当到达的高度加进应当到达的坐标,这就是相机的新位置

m_transsform.position=Vector3.Lerp(m_transsform.position,m_position,Time.time);

m_transsform.LookAt(m_player);//注视玩家

RaycastHithit;//定义一条从玩家到相机位置的射线

if(Physics.Linecast(m_player.position+Vector3.up,m_transsform.position,outhit))

{

stringname=hit.collider.gameObject.tag;

if(name!

="MainCamera")

{

floatcurrentDistance=Vector3.Distance(hit.point,m_player.position);//如果射线碰撞的不是相机,那么就取得射线碰撞点到玩家的距离

if(currentDistance

{

m_transsform.position=hit.point;

}

}

}

具体远理大概就是使用一条从玩家角色位置发射的射线,当碰撞到任何不属于相机的物体时,就拉近相机的位置,避免“穿墙”的发生。

好了,相机的脚本差不多完成了!

现在保存脚本,将角色的标签设置为“Player”,然后把MyCamera脚本拖给场景中的相机,运行游戏,相机就会跟随角色一块运动了!

碰上什么障碍物的话,就会直接拉近相机了。

如图:

 

OK!

那么接下来就把地面先画了罢。

现在画面黑漆漆的不好看,所以首先先创建一个平行光。

然后在地形的Texture一项中选中一张草坪样的图片,并将size设置为5*5,场景就全变绿了。

然后在_Script中再创建一个DayAndNight脚本,意为控制昼夜交替和时间的。

虽然对于ARPG游戏来说,昼夜交替并非必要,而且玩这个游戏的人恐怕也很少会注意到.....不过我鼓捣了好久,还是决定把更真实的效果加进去(虽然只是自己鼓捣出来的一种仿冒效果!

)。

在脚本最前面,依然定义几个变量,分别代表分钟和小时(游戏里是绝不敢弄成现实一致的....):

publicfloatm_minute=1;

publicintm_hour=20;

publicTransformm_tramsform;

Start函数中取得自身的对象:

m_tramsform=this.transform;

然后在Update函数中每秒对分钟数进行递增,并判断分钟数是否大于六十,大于六十的话,小时数就加一,并把分钟数置为0:

m_minute+=Time.deltaTime;

if(m_minute>=60)

{

m_hour++;

m_minute=0;

if(m_hour==24)

{

m_hour=0;

}

}

接下来就是对天空盒的更换,首先导入系统自带的天空盒资源包,然后在根目录中新建一个Resources文件夹,将导入的天空盒相应材质移动到Resources文件夹下。

我数学不好,也没去计算什么太阳角度之类的的了,直接用了最笨的方法(请不要在意细节啦!

),应该也是最直观的,想法那就是定义24个小时,然后在每一个小时都对平行光的角度进行设置,然后在固定的时刻改变天空盒。

这样各种事物的光影效果也会有了:

Quaternionm_temp;

switch(m_hour)

{

case1:

m_temp=Quaternion.Euler(-75,0,0);

m_tramsform.rotation=m_temp;

break;

case2:

m_temp=Quaternion.Euler(-60,0,0);

m_tramsform.rotation=m_temp;

break;

case3:

m_temp=Quaternion.Euler(-45,0,0);

m_tramsform.rotation=m_temp;

break;

case4:

m_temp=Quaternion.Euler(-30,0,0);

m_tramsform.rotation=m_temp;

break;

case5:

m_temp=Quaternion.Euler(-15,0,0);

m_tramsform.rotation=m_temp;

RenderSettings.skybox=(Material)Resources.Load("Overcast2Skybox");//黎明

break;

case6:

m_temp=Quaternion.Euler(0,0,0);

m_tramsform.rotation=m_temp;

break;

case7:

m_temp=Quaternion.Euler(15,0,0);

m_tramsform.rotation=m_temp;

RenderSettings.skybox=(Material)Resources.Load("Sunny1Skybox");//早上

break;

case8:

m_temp=Quaternion.Euler(30,0,0);

m_tramsform.rotation=m_temp;

break;

case9:

m_temp=Quaternion.Euler(45,0,0);

m_tramsform.rotation=m_temp;Quaternion.Slerp(m_tramsform.rotation,m_temp,Time.deltaTime);

break;

case10:

m_temp=Quaternion.Euler(60,0,0);

m_tramsform.rotation=m_temp;

break;

case11:

m_temp=Quaternion.Euler(75,0,0);

m_tramsform.rotation=m_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1