Unity3d 中MeshColliderwin7旧版组件打勾下convex勾选有什么用?

unity3d常用组件及分析
无法运行,请执行js权限
29.unity常用的collider
下载APP离线观看
C#是微软公司在2000年7月发布的一种全新且简单、安全、面向对象的程序设计语言,是专门为.NET的应用而开发的语言,并且做为Unity3d的脚本语言之一,。它吸收了C++、Visual Basic、Delphi、Java等语言的优点,体现了当今最新的程序设计技术的功能和精华。C#继承了C语言的语法风格,同时又继承了C++的面向对象特性。课程全面讲述了C#基础知识,带您进入C#的精彩世界, 了解C#的基础知识及如何快速学习C#,课程内容主要分为以下几部分。
1. C#基础语法,流程控制语句。(变量的定义,数据的类型,字符串处理,集合的处理)
2. C#的面向对象编程(类的定义,方法的应用,四种传参方法,字段的封装,方法的重构,类的继承,静态类,抽象类,接口等)
3. C#的IO处理,事件委托,多线程开发,异常处理等
4. C#对于XML的处理(游戏有可能有Xml的配置文件,需要读取操作)
个人介绍:
钟勇:多年一线.net开发经验以及软件培训经验,成都微软技术中心技术专家之一,国家信息安全产业基地(西部)技术顾问。精通c#技术,php技术,参与项目涉及电子政务系统、网上银行、ERP、CRM、OA等。
从零开始一步一步讲解Unity3D,介绍引擎的方方面面,在学习完本课程后,同学们能熟悉合和了解整个Unity3D的操作流程和方法,能正式开始游戏项目的研发了。
从零开始一步一步讲解Unity3D,介绍引擎的方方面面,在学习完本课程后,同学们能熟悉合和了解整个Unity3D的操作流程和方法,能正式开始游戏项目的研发了.
该课程学习如何控制角色,以及处理游戏场景内的物理相关的情况,同时学习如何给我们的场景添加粒子特效,学习完成后就能灵活控制我们的角色,同时知道如何处理碰撞或者其他运动的情况,学会粒子系统过后能让我们的场景绚丽和丰富起来。
只看我参与的
mesh collier 的添加是模型的mesh吗,这个需要怎么准备好?
加载更多↓
1——10 课件
1——10 课件
11——13 课件
11——13 课件
选择反馈类型
请选择分类
请选择反馈类型
你还可以输入200字
请留下你的宝贵意见!~
请留下正确的电话号码,以便我们能帮助你!
滑动完成验证
请滑动进行验证
感谢你的反馈,你的支持永远是我们前进的动力!
亲爱的学员
该课程还有更完整的职业课程大纲哦~
体系化学习,会有更好的学习效果!
直通班课程
抱歉,该课程视频仅限该直通班学员观看哦~
立即报名,您可享有
免费观看所有课程视频
智能在线学习系统
名师小班指导
全国就业服务
还没有账号?
其他方式登录
滑动完成验证
重发验证码
手机短信验证码已发送,请查收!
老板不在,1月折扣疯狂放送!
客服热线 400-862-8862他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Unity3D 官方案例 SpaceShooter 开发教程a year ago代码心得:限制需要在Game视图移动来调节。记住了rigidbody的velocity方法,限制Player的飞行范围可通过rigidbody.position来控制。学习了Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax)的用法。学习了系列化[System.Serializable]在窗口视图中显示。6、创建一个GameObject,改名为Bolt,创建一个GameObject,改名为VFX,放到Bolt下,将fx_lazer_orange_dff拖到VFX Inspector中,将Shader改为Particles/Additive可将背景设置为透明。给Bolt加上RigidBody,去掉use Gravity.添加Mover脚本:using UnityE
using System.C
public class Mover : MonoBehaviour {
public float speed = 20f;
// Use this for initialization
void Start () {
rigidbody.velocity = transform.forward *
再添加一个Capsule Collider用于碰撞检测,将Radius和height的值设为0.05,0.55.direction设为Z-Axis,现在报错,是因为FBX的MeshRenderer和Bolt的Capsule Collider冲突,删掉FBX的MeshRenderer。注意一点要想把改变的同步到Prefabs中就得点击应用。
开始添加子弹,创建新的GameObject,命名为SpawnPos放到Player下面。继续编辑PlayerController脚本。代码如下:
using UnityE
using System.C
[System.Serializable]
public class Boundary
public float zMin = -3.3f;
public float zMax = 14f;
public float xMin = -6.5f;
public float xMax = 6.5f;
public class PlayerController : MonoBehaviour {
public float speed = 10f;
public GameO
public Transform spawnP
void Update()
if(Input.GetButton("Fire1"))
Instantiate(bolt, spawnPos.position, spawnPos.rotation);
void FixedUpdate()
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 move = new Vector3(h, 0, v);
rigidbody.velocity = speed *
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
问题:运行游戏,发现游戏的子弹是散的。将Bolt里面的is Trigger勾选上可防止这种情况的出现。现在发现子弹的发射过于连续,添加代码:using UnityE
using System.C
[System.Serializable]
public class Boundary
public float zMin = -3.3f;
public float zMax = 14f;
public float xMin = -6.5f;
public float xMax = 6.5f;
public class PlayerController : MonoBehaviour {
public float speed = 10f;
public GameO
public Transform spawnP
public float fireRate = 0.1f;
private float nextF
void Update()
if(Input.GetButton("Fire1") && Time.time & nextFire)
nextFire = Time.time + fireR
Instantiate(bolt, spawnPos.position, spawnPos.rotation);
void FixedUpdate()
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 move = new Vector3(h, 0, v);
rigidbody.velocity = speed *
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
Bolt(clone)不会消失,现在开始制作子弹的边界。创建一个cube,改名为Boundary,将Box Collider的Size改为15 和 30,位置调节到与Background位置一致。删除掉mesh collider等组件,添加脚本DesdroyByBoundary。代码如下:using UnityE
using System.C
public class DestroyByBoundary : MonoBehaviour
void OnTriggerExit(Collider other)
Destroy(other.gameObject);
现在开始创建陨石,创建新的GameObject,改名为Asteroid,将prop_asteroid_01拖入其中,添加Rigidbody和Capsule Collider,修改参数使Capsule Collider与物体差不多吻合。RigidBody去掉use Gravity.添加一个脚本,RandomRotation,代码如下:using UnityE
using System.C
public class RandomRotation : MonoBehaviour {
public float tumble = 5;
// Use this for initialization
void Start () {
rigidbody.angularVelocity = Random.insideUnitSphere *
Asteroid添加一个Mover,改Speed为-5。现在陨石可以向下旋转且下落。同理添加Asteroid2和Asteroid3.添加一个脚本,改名为DestroyByCantact,如下:using UnityE
using System.C
public class DestroyByCantact : MonoBehaviour {
void OnTriggerEnter(Collider other)
if (other.gameObject.tag == "Boundary")
Destroy(other.gameObject);
Destroy(this.gameObject);
添加到各个Asteroid中。
DestroyByCantact添加代码:
using UnityE
using System.C
public class DestroyByCantact : MonoBehaviour {
public GameO
public GameObject playerE
void OnTriggerEnter(Collider other)
if (other.gameObject.tag == "Boundary")
if(other.gameObject.tag == "player")
Instantiate(playerExplosion, this.transform.position, this.transform.rotation);
Destroy(other.gameObject);
Destroy(this.gameObject);
Instantiate(explossion, this.transform.position, this.transform.rotation);
将各个爆炸效果分别拖到脚本中,应用到Prefabs当中。接下来给GameCotroller脚本加代码:using UnityE
using System.C
public class GameController : MonoBehaviour
public Vector3 spawnV
public GameObject[]
// Use this for initialization
void Start()
// Update is called once per frame
void Update()
if (Random.value & 0.1)
void Spawn()
GameObject o = hazards[Random.Range(0, hazards.Length)];
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion q = Quaternion.
Instantiate(o, p, q);
将三个陨石分别添加到Hazards里面。继续修改GameController代码:using UnityE
using System.C
public class GameController : MonoBehaviour
public Vector3 spawnV
public GameObject[]
public int numPerWave = 10;
public float startWait = 2f;
//出现小行星之前的等待时间
public float spanWait = 1f;
//一波小行星内的间隔时间
public float waveWait = 4f;
//每两波时间间隔
// Use this for initialization
void Start()
StartCoroutine(SpawnWaves());
// Update is called once per frame
void Update()
//if (Random.value & 0.1)
IEnumerator SpawnWaves()
yield return new WaitForSeconds(startWait);
while(true)
for (int i = 0; i & numPerW i++)
yield return new WaitForSeconds(spanWait);
yield return new WaitForSeconds(waveWait);
private void WaitForSeconds(float spanWait)
throw new System.NotImplementedException();
void Spawn()
GameObject o = hazards[Random.Range(0, hazards.Length)];
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion q = Quaternion.
Instantiate(o, p, q);
里面涉及到技巧性。添加音效,有几个可以直接添加。对于player发射子弹的声音可以在代码中添加。using UnityE
using System.C
[System.Serializable]
public class Boundary
public float zMin = -3.3f;
public float zMax = 14f;
public float xMin = -6.5f;
public float xMax = 6.5f;
public class PlayerController : MonoBehaviour {
public float speed = 10f;
public GameO
public Transform spawnP
public float fireRate = 0.1f;
private float nextF
public AudioC
void Update()
if(Input.GetButton("Fire1") && Time.time & nextFire)
nextFire = Time.time + fireR
Instantiate(bolt, spawnPos.position, spawnPos.rotation);
audio.PlayOneShot(fire);
void FixedUpdate()
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 move = new Vector3(h, 0, v);
rigidbody.velocity = speed *
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));
添加脚本将爆炸效果去除创建DestroyByTime,如下:using UnityE
using System.C
public class DestroyByTime : MonoBehaviour {
public float lifeTime = 2;
// Use this for initialization
void Start () {
Destroy(this.gameObject, lifeTime);
// Update is called once per frame
void Update () {
添加分数,创建一个GUIText,修改y为1,修改代码GameControllerusing UnityE
using System.C
public class GameController : MonoBehaviour
public Vector3 spawnV
public GameObject[]
public int numPerWave = 10;
public float startWait = 2f;
//出现小行星之前的等待时间
public float spanWait = 1f;
//一波小行星内的间隔时间
public float waveWait = 4f;
//每两波时间间隔
public GUIText scoreT
// Use this for initialization
void Start()
StartCoroutine(SpawnWaves());
scoreText.text = "Score: " +
// Update is called once per frame
void Update()
//if (Random.value & 0.1)
IEnumerator SpawnWaves()
yield return new WaitForSeconds(startWait);
while(true)
for (int i = 0; i & numPerW i++)
yield return new WaitForSeconds(spanWait);
yield return new WaitForSeconds(waveWait);
private void WaitForSeconds(float spanWait)
throw new System.NotImplementedException();
void Spawn()
GameObject o = hazards[Random.Range(0, hazards.Length)];
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion q = Quaternion.
Instantiate(o, p, q);
public void AddScore(int v)
scoreText.text = "Score: " +
将GameController物体的TAG改为GameController,修改DesdroyByContact脚本:using UnityE
using System.C
public class DestroyByCantact : MonoBehaviour {
public GameO
public GameObject playerE
private GameController gameC
public int score = 10;
void Start()
GameObject gameControllerObject = GameObject.FindWithTag("GameController");
if(gameControllerObject != null)
gameController = gameControllerObject.GetComponent&GameController&();
if(gameControllerObject == null)
Debug.Log("TaoCheng");
void OnTriggerEnter(Collider other)
if (other.gameObject.tag == "Boundary")
if(other.gameObject.tag == "player")
Instantiate(playerExplosion, this.transform.position, this.transform.rotation);
if(other.gameObject.tag == "enemy")
Destroy(other.gameObject);
gameController.AddScore(score);
Destroy(this.gameObject);
Instantiate(explossion, this.transform.position, this.transform.rotation);
做显示游戏结束和游戏重新开始。GameCotroller脚本代码如下:using UnityE
using System.C
public class GameController : MonoBehaviour
public Vector3 spawnV
public GameObject[]
public int numPerWave = 10;
public float startWait = 2f;
//出现小行星之前的等待时间
public float spanWait = 1f;
//一波小行星内的间隔时间
public float waveWait = 4f;
//每两波时间间隔
public GUIText scoreT
private bool gameO
public GUIText gameOverT
public GUIText helpT
// Use this for initialization
void Start()
StartCoroutine(SpawnWaves());
scoreText.text = "Score: " +
gameOverText.text = "";
helpText.text = "";
// Update is called once per frame
void Update()
if(gameOver && Input.GetKeyDown(KeyCode.R))
Application.LoadLevel(Application.loadedLevel);
//if (Random.value & 0.1)
IEnumerator SpawnWaves()
yield return new WaitForSeconds(startWait);
while(true)
for (int i = 0; i & numPerW i++)
yield return new WaitForSeconds(spanWait);
yield return new WaitForSeconds(waveWait);
if (gameOver)
private void WaitForSeconds(float spanWait)
throw new System.NotImplementedException();
void Spawn()
GameObject o = hazards[Random.Range(0, hazards.Length)];
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion q = Quaternion.
Instantiate(o, p, q);
public void AddScore(int v)
scoreText.text = "Score: " +
public void GameOver()
gameOver =
gameOverText.text = "Game Over!";
helpText.text = "Press 'R' to Restart!";
DestroyByContact脚本代码如下:using UnityE
using System.C
public class DestroyByCantact : MonoBehaviour {
public GameO
public GameObject playerE
private GameController gameC
public int score = 10;
void Start()
GameObject gameControllerObject = GameObject.FindWithTag("GameController");
if(gameControllerObject != null)
gameController = gameControllerObject.GetComponent&GameController&();
if(gameControllerObject == null)
Debug.Log("TaoCheng");
void OnTriggerEnter(Collider other)
if (other.gameObject.tag == "Boundary")
if(other.gameObject.tag == "Player")
Instantiate(playerExplosion, this.transform.position, this.transform.rotation);
gameController.GameOver();
Debug.Log("Error");
if(other.gameObject.tag == "enemy")
Destroy(other.gameObject);
gameController.AddScore(score);
Destroy(this.gameObject);
Instantiate(explossion, this.transform.position, this.transform.rotation);
设置一个GUIText组,分别添加到代码中。SpaceShooter基本功能完成。4收藏分享举报文章被以下专栏收录游戏开发/图形学/人工智能{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\u002Fpay.zhihu.com\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&游戏开发/图形学/人工智能&,&permission&:&COLUMN_PUBLIC&,&memberId&:6055222,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&游戏开发/图形学/人工智能&,&urlToken&:&VR2AR&,&id&:21572,&imagePath&:&v2-2f2f25d068ff2f651dc93.jpg&,&slug&:&VR2AR&,&applyReason&:&0&,&name&:&虚幻与真实&,&title&:&虚幻与真实&,&url&:&https:\u002F\u002Fzhuanlan.zhihu.com\u002FVR2AR&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:951,&avatar&:{&id&:&v2-2f2f25d068ff2f651dc93&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-2f2f25d068ff2f651dc93_l.jpg&,&articlesCount&:15},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-580ddd825b9fbb44e7696_r.jpg&,&lastUpdated&:,&imagePath&:&v2-580ddd825b9fbb44e7696.png&,&permission&:&ARTICLE_PUBLIC&,&topics&:[],&summary&:&1、先导入SpaceShooter的环境资源,将Models下的vehicle_playerShip放到Hierachy窗口,改名为Player.Rotation x改为270,为Player添加mesh collider组件,将vehicle_playerShip_collider放到Mesh属性里面,为Player添加刚体,去掉重力的勾选,将Prefebs中的…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T15:29:57+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:1544836,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&Unity3D 官方案例 SpaceShooter 开发教程&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:21572,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-580ddd825b9fbb44e7696_r.jpg&,&author&:{&bio&:&大盈若冲&,&isFollowing&:false,&hash&:&d49289bca0e883d50b67e&,&uid&:88,&isOrg&:false,&slug&:&FrancisTao&,&isFollowed&:false,&description&:&曾经的移动开发,游戏开发工程师。\n现在专注于数据分析。\n\n对万事万物都有好奇心。\n对一切持质疑态度。\n\n热爱读书,希望 30 岁之前能读完万卷书。\n但是读不完也没所谓。更重要的是致知于行。\n尤其喜欢商业,投资和心理学。\n\n95 年人,还很年轻,要学的还很多。\n我的微信:\n欢迎有意思的人来和我聊聊。\n\n约稿,转载和数据分析外包业务以及靠谱创业团队请私信。\n有问题请值乎提问。&,&name&:&谛听烛九阴&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002FFrancisTao&,&avatar&:{&id&:&v2-e3699fac96ec49cd9602bb64&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:6055222,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:464193}],&title&:&Unity3D 官方案例 SpaceShooter 开发教程&,&author&:&FrancisTao&,&content&:&1、先导入SpaceShooter的环境资源,将Models下的vehicle_playerShip放到Hierachy窗口,改名为Player.Rotation x改为270,为Player添加mesh collider组件,将vehicle_playerShip_collider放到Mesh属性里面,为Player添加刚体,去掉重力的勾选,将Prefebs中的engines_player放到Hierarchy,并调好位置。\u003Cbr\u003E2、进入3D视图,将MainCamera中的Projection改为Orthographic,摄像机视图变为矩形视图。将Camered的背景改为黑色。将Player的Rotation x 改为零。Camera的Rotation改为90,移动摄像机,调节位置在Game视图中查看。通过调节Camera的Size来调节Player的大小,通过调节Camera的Position来调节Player的位置,适当即可。\u003Cbr\u003E3、添加一个Directional Light,改名为Main Light,然后reset,改Rotation x为20,y为245.Intensity改为0.75,同理继续添加一个,改名为Fill Light,将Rotation y改为125,点开color将RGB分别改为128,192,192.在添加一个Rim Light,将Rotation x,y分别改为345,65,Indensity改为0.25,Ctrl+Shift+N创建一个GameObject,改名为Light,将三个Light放进去。\u003Cbr\u003E4、添加一个Quad组件,改名为Background,rotation x 90,添加一个纹理tile_nebula_green_dff,将tile_nebula_green_dff中的shader改为Unlity\u002FTexture,将Position y 改为-10,将Scale x, y改为15和30,这是纹理图片的大小比例决定的,1:2。\u003Cbr\u003E5、创建GameObject,改名为GameCotroller,添加脚本GameCotroller.cs,为Player添加一个新的脚本,命名为PlayerController,脚本为:\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\n[System.Serializable]\npublic class Boundary\n{\n
public float zMin = -3.3f;\n
public float zMax = 14f;\n
public float xMin = -6.5f;\n
public float xMax = 6.5f;\n}\npublic class PlayerController : MonoBehaviour {\n
public float speed = 10f;\n
public B\n
void FixedUpdate()\n
float h = Input.GetAxis(\&Horizontal\&);\n
float v = Input.GetAxis(\&Vertical\&);\n
Vector3 move = new Vector3(h, 0, v);\n
rigidbody.velocity = speed *\n
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E代码心得:限制需要在Game视图移动来调节。记住了rigidbody的velocity方法,限制Player的飞行范围可通过rigidbody.position来控制。学习了Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax)的用法。学习了系列化[System.Serializable]在窗口视图中显示。\u003Cbr\u003E6、创建一个GameObject,改名为Bolt,创建一个GameObject,改名为VFX,放到Bolt下,将fx_lazer_orange_dff拖到VFX Inspector中,将Shader改为Particles\u002FAdditive可将背景设置为透明。给Bolt加上RigidBody,去掉use Gravity.添加Mover脚本:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class Mover : MonoBehaviour {\n
public float speed = 20f;\n \u002F\u002F Use this for initialization\n void Start () {\n
rigidbody.velocity = transform.forward *\n }\n}\n再添加一个Capsule Collider用于碰撞检测,将Radius和height的值设为0.05,0.55.direction设为Z-Axis,现在报错,是因为FBX的MeshRenderer和Bolt的Capsule Collider冲突,删掉FBX的MeshRenderer。注意一点要想把改变的同步到Prefabs中就得点击应用。\n开始添加子弹,创建新的GameObject,命名为SpawnPos放到Player下面。继续编辑PlayerController脚本。代码如下:\nusing UnityE\nusing System.C\n[System.Serializable]\npublic class Boundary\n{\n
public float zMin = -3.3f;\n
public float zMax = 14f;\n
public float xMin = -6.5f;\n
public float xMax = 6.5f;\n}\npublic class PlayerController : MonoBehaviour {\n
public float speed = 10f;\n
public B\n
public GameO\n
public Transform spawnP\n
void Update()\n
if(Input.GetButton(\&Fire1\&))\n
Instantiate(bolt, spawnPos.position, spawnPos.rotation);\n
void FixedUpdate()\n
float h = Input.GetAxis(\&Horizontal\&);\n
float v = Input.GetAxis(\&Vertical\&);\n
Vector3 move = new Vector3(h, 0, v);\n
rigidbody.velocity = speed *\n
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E问题:运行游戏,发现游戏的子弹是散的。将Bolt里面的is Trigger勾选上可防止这种情况的出现。现在发现子弹的发射过于连续,添加代码:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\n[System.Serializable]\npublic class Boundary\n{\n
public float zMin = -3.3f;\n
public float zMax = 14f;\n
public float xMin = -6.5f;\n
public float xMax = 6.5f;\n}\npublic class PlayerController : MonoBehaviour {\n
public float speed = 10f;\n
public B\n
public GameO\n
public Transform spawnP\n
public float fireRate = 0.1f;\n
private float nextF\n
void Update()\n
if(Input.GetButton(\&Fire1\&) && Time.time & nextFire)\n
nextFire = Time.time + fireR\n
Instantiate(bolt, spawnPos.position, spawnPos.rotation);\n
void FixedUpdate()\n
float h = Input.GetAxis(\&Horizontal\&);\n
float v = Input.GetAxis(\&Vertical\&);\n
Vector3 move = new Vector3(h, 0, v);\n
rigidbody.velocity = speed *\n
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003EBolt(clone)不会消失,现在开始制作子弹的边界。\u003Cbr\u003E创建一个cube,改名为Boundary,将Box Collider的Size改为15 和 30,位置调节到与Background位置一致。删除掉mesh collider等组件,添加脚本DesdroyByBoundary。代码如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class DestroyByBoundary : MonoBehaviour\n{\n
void OnTriggerExit(Collider other)\n
Destroy(other.gameObject);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E现在开始创建陨石,创建新的GameObject,改名为Asteroid,将prop_asteroid_01拖入其中,添加Rigidbody和Capsule Collider,修改参数使Capsule Collider与物体差不多吻合。RigidBody去掉use Gravity.添加一个脚本,RandomRotation,代码如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class RandomRotation : MonoBehaviour {\n
public float tumble = 5;\n \u002F\u002F Use this for initialization\n void Start () {\n
rigidbody.angularVelocity = Random.insideUnitSphere *\n }\n \n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003EAsteroid添加一个Mover,改Speed为-5。现在陨石可以向下旋转且下落。\u003Cbr\u003E同理添加Asteroid2和Asteroid3.\u003Cbr\u003E添加一个脚本,改名为DestroyByCantact,如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class DestroyByCantact : MonoBehaviour {\n void OnTriggerEnter(Collider other)\n
if (other.gameObject.tag == \&Boundary\&) \n
Destroy(other.gameObject);\n
Destroy(this.gameObject);\n
}\n}\n添加到各个Asteroid中。\nDestroyByCantact添加代码:\nusing UnityE\nusing System.C\npublic class DestroyByCantact : MonoBehaviour {\n
public GameO\n
public GameObject playerE\n void OnTriggerEnter(Collider other)\n
if (other.gameObject.tag == \&Boundary\&) \n
if(other.gameObject.tag == \&player\&)\n
Instantiate(playerExplosion, this.transform.position, this.transform.rotation);\n
Destroy(other.gameObject);\n
Destroy(this.gameObject);\n
Instantiate(explossion, this.transform.position, this.transform.rotation);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E将各个爆炸效果分别拖到脚本中,应用到Prefabs当中。\u003Cbr\u003E接下来给GameCotroller脚本加代码:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class GameController : MonoBehaviour\n{\n
public Vector3 spawnV\n
public GameObject[]\n
\u002F\u002F Use this for initialization\n
void Start()\n
\u002F\u002F Update is called once per frame\n
void Update()\n
if (Random.value & 0.1)\n
Spawn();\n
void Spawn()\n
GameObject o = hazards[Random.Range(0, hazards.Length)];\n
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);\n
Quaternion q = Quaternion.\n
Instantiate(o, p, q);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E将三个陨石分别添加到Hazards里面。\u003Cbr\u003E继续修改GameController代码:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class GameController : MonoBehaviour\n{\n
public Vector3 spawnV\n
public GameObject[]\n
public int numPerWave = 10;\n
public float startWait = 2f;
\u002F\u002F出现小行星之前的等待时间\n
public float spanWait = 1f;
\u002F\u002F一波小行星内的间隔时间\n
public float waveWait = 4f;
\u002F\u002F每两波时间间隔\n
\u002F\u002F Use this for initialization\n
void Start()\n
StartCoroutine(SpawnWaves());\n
\u002F\u002F Update is called once per frame\n
void Update()\n
\u002F\u002Fif (Random.value & 0.1)\n
\u002F\u002F{\n
\u002F\u002F
Spawn();\n
\u002F\u002F}\n
IEnumerator SpawnWaves()\n
yield return new WaitForSeconds(startWait);\n
while(true)\n
for (int i = 0; i & numPerW i++)\n
Spawn();\n
yield return new WaitForSeconds(spanWait);\n
yield return new WaitForSeconds(waveWait);\n
private void WaitForSeconds(float spanWait)\n
throw new System.NotImplementedException();\n
void Spawn()\n
GameObject o = hazards[Random.Range(0, hazards.Length)];\n
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);\n
Quaternion q = Quaternion.\n
Instantiate(o, p, q);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E里面涉及到技巧性。\u003Cbr\u003E添加音效,有几个可以直接添加。对于player发射子弹的声音可以在代码中添加。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\n[System.Serializable]\npublic class Boundary\n{\n
public float zMin = -3.3f;\n
public float zMax = 14f;\n
public float xMin = -6.5f;\n
public float xMax = 6.5f;\n}\npublic class PlayerController : MonoBehaviour {\n
public float speed = 10f;\n
public B\n
public GameO\n
public Transform spawnP\n
public float fireRate = 0.1f;\n
private float nextF\n
public AudioC\n
void Update()\n
if(Input.GetButton(\&Fire1\&) && Time.time & nextFire)\n
nextFire = Time.time + fireR\n
Instantiate(bolt, spawnPos.position, spawnPos.rotation);\n
audio.PlayOneShot(fire);\n
void FixedUpdate()\n
float h = Input.GetAxis(\&Horizontal\&);\n
float v = Input.GetAxis(\&Vertical\&);\n
Vector3 move = new Vector3(h, 0, v);\n
rigidbody.velocity = speed *\n
rigidbody.position = new Vector3(Mathf.Clamp(rigidbody.position.x, bound.xMin, bound.xMax), 0, Mathf.Clamp(rigidbody.position.z, bound.zMin, bound.zMax));\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E添加脚本将爆炸效果去除\u003Cbr\u003E创建DestroyByTime,如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class DestroyByTime : MonoBehaviour {\n
public float lifeTime = 2;\n \u002F\u002F Use this for initialization\n void Start () {\n
Destroy(this.gameObject, lifeTime);\n }\n \n \u002F\u002F Update is called once per frame\n void Update () {\n \n }\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E添加分数,创建一个GUIText,修改y为1,修改代码GameController\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class GameController : MonoBehaviour\n{\n
public Vector3 spawnV\n
public GameObject[]\n
public int numPerWave = 10;\n
public float startWait = 2f;
\u002F\u002F出现小行星之前的等待时间\n
public float spanWait = 1f;
\u002F\u002F一波小行星内的间隔时间\n
public float waveWait = 4f;
\u002F\u002F每两波时间间隔\n
public GUIText scoreT\n \n
\u002F\u002F Use this for initialization\n
void Start()\n
StartCoroutine(SpawnWaves());\n
scoreText.text = \&Score: \& +\n
\u002F\u002F Update is called once per frame\n
void Update()\n
\u002F\u002Fif (Random.value & 0.1)\n
\u002F\u002F{\n
\u002F\u002F
Spawn();\n
\u002F\u002F}\n
IEnumerator SpawnWaves()\n
yield return new WaitForSeconds(startWait);\n
while(true)\n
for (int i = 0; i & numPerW i++)\n
Spawn();\n
yield return new WaitForSeconds(spanWait);\n
yield return new WaitForSeconds(waveWait);\n
private void WaitForSeconds(float spanWait)\n
throw new System.NotImplementedException();\n
void Spawn()\n
GameObject o = hazards[Random.Range(0, hazards.Length)];\n
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);\n
Quaternion q = Quaternion.\n
Instantiate(o, p, q);\n
public void AddScore(int v)\n
score +=\n
scoreText.text = \&Score: \& +\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E将GameController物体的TAG改为GameController,修改DesdroyByContact脚本:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class DestroyByCantact : MonoBehaviour {\n
public GameO\n
public GameObject playerE\n
private GameController gameC\n
public int score = 10;\n
void Start()\n
GameObject gameControllerObject = GameObject.FindWithTag(\&GameController\&);\n
if(gameControllerObject != null)\n
gameController = gameControllerObject.GetComponent&GameController&();\n
if(gameControllerObject == null)\n
Debug.Log(\&TaoCheng\&);\n
}\n void OnTriggerEnter(Collider other)\n
if (other.gameObject.tag == \&Boundary\&) \n
if(other.gameObject.tag == \&player\&)\n
Instantiate(playerExplosion, this.transform.position, this.transform.rotation);\n
if(other.gameObject.tag == \&enemy\&)\n
Destroy(other.gameObject);\n
gameController.AddScore(score);\n
Destroy(this.gameObject);\n
Instantiate(explossion, this.transform.position, this.transform.rotation);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E做显示游戏结束和游戏重新开始。\u003Cbr\u003EGameCotroller脚本代码如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class GameController : MonoBehaviour\n{\n
public Vector3 spawnV\n
public GameObject[]\n
public int numPerWave = 10;\n
public float startWait = 2f;
\u002F\u002F出现小行星之前的等待时间\n
public float spanWait = 1f;
\u002F\u002F一波小行星内的间隔时间\n
public float waveWait = 4f;
\u002F\u002F每两波时间间隔\n
public GUIText scoreT\n \n
private bool gameO\n
public GUIText gameOverT\n
public GUIText helpT\n
\u002F\u002F Use this for initialization\n
void Start()\n
StartCoroutine(SpawnWaves());\n
scoreText.text = \&Score: \& +\n
gameOverText.text = \&\&;\n
helpText.text = \&\&;\n
\u002F\u002F Update is called once per frame\n
void Update()\n
if(gameOver && Input.GetKeyDown(KeyCode.R))\n
Application.LoadLevel(Application.loadedLevel);\n
\u002F\u002Fif (Random.value & 0.1)\n
\u002F\u002F{\n
\u002F\u002F
Spawn();\n
\u002F\u002F}\n
IEnumerator SpawnWaves()\n
yield return new WaitForSeconds(startWait);\n
while(true)\n
for (int i = 0; i & numPerW i++)\n
Spawn();\n
yield return new WaitForSeconds(spanWait);\n
yield return new WaitForSeconds(waveWait);\n
if (gameOver) \n \n
private void WaitForSeconds(float spanWait)\n
throw new System.NotImplementedException();\n
void Spawn()\n
GameObject o = hazards[Random.Range(0, hazards.Length)];\n
Vector3 p = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);\n
Quaternion q = Quaternion.\n
Instantiate(o, p, q);\n
public void AddScore(int v)\n
score +=\n
scoreText.text = \&Score: \& +\n
public void GameOver()\n
gameOver =\n
gameOverText.text = \&Game Over!\&;\n
helpText.text = \&Press 'R' to Restart!\&;\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003EDestroyByContact脚本代码如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Eusing UnityE\nusing System.C\npublic class DestroyByCantact : MonoBehaviour {\n
public GameO\n
public GameObject playerE\n
private GameController gameC\n
public int score = 10;\n
void Start()\n
GameObject gameControllerObject = GameObject.FindWithTag(\&GameController\&);\n
if(gameControllerObject != null)\n
gameController = gameControllerObject.GetComponent&GameController&();\n
if(gameControllerObject == null)\n
Debug.Log(\&TaoCheng\&);\n
}\n void OnTriggerEnter(Collider other)\n
if (other.gameObject.tag == \&Boundary\&) \n
if(other.gameObject.tag == \&Player\&)\n
Instantiate(playerExplosion, this.transform.position, this.transform.rotation);\n
gameController.GameOver();\n
Debug.Log(\&Error\&);\n
if(other.gameObject.tag == \&enemy\&)\n
Destroy(other.gameObject);\n
gameController.AddScore(score);\n
Destroy(this.gameObject);\n
Instantiate(explossion, this.transform.position, this.transform.rotation);\n
}\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E设置一个GUIText组,分别添加到代码中。\u003Cbr\u003ESpaceShooter基本功能完成。\u003C\u002Fp\u003E&,&updated&:new Date(&T07:29:57.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:7,&collapsedCount&:0,&likeCount&:4,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-580ddd825b9fbb44e7696_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&Unity(游戏引擎)&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&游戏开发&}],&adminClosedComment&:false,&titleImageSize&:{&width&:580,&height&:388},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&VR2AR&,&name&:&虚幻与真实&},&tipjarState&:&inactivated&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:7,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T15:29:57+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&知识浅薄的人&,&isFollowing&:false,&hash&:&1d843cbf9115&,&uid&:499500,&isOrg&:false,&slug&:&li-meng-jun-70-7&,&isFollowed&:false,&description&:&太无聊,不得已找些以后能赚钱的事情做做&,&name&:&李猛俊&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fli-meng-jun-70-7&,&avatar&:{&id&:&9e46b6a75bc97b92bbdb3dfdd6fde572&,&template&:&https:\u002F\u002Fpic4.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&Good Day.&,&isFollowing&:false,&hash&:&e797fb69d75cbd14b845&,&uid&:524700,&isOrg&:false,&slug&:&porphyah&,&isFollowed&:false,&description&:&Working in Progress...&,&name&:&Porphyah&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fporphyah&,&avatar&:{&id&:&v2-fc4b6c50ca66ccbca52c0b8&,&template&:&https:\u002F\u002Fpic3.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&索狗\u002F学生狗\u002F轻度主机玩家&,&isFollowing&:false,&hash&:&ab0e331c822f88d5ad7cce2ece9649c2&,&uid&:993300,&isOrg&:false,&slug&:&guo-hou-xiao&,&isFollowed&:false,&description&:&考研考研考研!&,&name&:&ErisRolo&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fguo-hou-xiao&,&avatar&:{&id&:&11f85dc41b233b2bd9d6e518fd745241&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&游戏研究僧&,&isFollowing&:false,&hash&:&cf48cdb69a8c93ca60bf3be61ab0d9d7&,&uid&:737700,&isOrg&:false,&slug&:&vermouthstx&,&isFollowed&:false,&description&:&&,&name&:&Vermouthstx&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002Fvermouthstx&,&avatar&:{&id&:&v2-f672f070f32ea4cde226d0c&,&template&:&https:\u002F\u002Fpic3.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&1、先导入SpaceShooter的环境资源,将Models下的vehicle_playerShip放到Hierachy窗口,改名为Player.Rotation x改为270,为Player添加mesh collider组件,将vehicle_playerShip_collider放到Mesh属性里面,为Player添加刚体,去掉重力的勾选,将Prefebs中的…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\u002Fpic4.zhimg.com\u002F50\u002Fv2-885d8dfbc05c865e4aaff56a8bec7418_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&虚幻引擎&},{&url&:&https:\u002F\u002Fwww.zhihu.com\u002Ftopic\u002F&,&id&:&&,&name&:&游戏开发&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&大盈若冲&,&isFollowing&:false,&hash&:&d49289bca0e883d50b67e&,&uid&:88,&isOrg&:false,&slug&:&FrancisTao&,&isFollowed&:false,&description&:&曾经的移动开发,游戏开发工程师。\n现在专注于数据分析。\n\n对万事万物都有好奇心。\n对一切持质疑态度。\n\n热爱读书,希望 30 岁之前能读完万卷书。\n但是读不完也没所谓。更重要的是致知于行。\n尤其喜欢商业,投资和心理学。\n\n95 年人,还很年轻,要学的还很多。\n我的微信:\n欢迎有意思的人来和我聊聊。\n\n约稿,转载和数据分析外包业务以及靠谱创业团队请私信。\n有问题请值乎提问。&,&name&:&谛听烛九阴&,&profileUrl&:&https:\u002F\u002Fwww.zhihu.com\u002Fpeople\u002FFrancisTao&,&avatar&:{&id&:&v2-e3699fac96ec49cd9602bb64&,&template&:&https:\u002F\u002Fpic2.zhimg.com\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&VR2AR&,&name&:&虚幻与真实&},&content&:&\u003Cp\u003E\u003Cb\u003EUnreal4 Framework\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E\u003Cb\u003EObject\u003C\u002Fb\u003E 所有类的基类,不能生成或放到游戏中,但是可以包含数据或者是函数相关内容。\u003Cbr\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EActor\u003C\u002Fb\u003E 场景中可独立存在的每个对象,支持三维变换的通用的类,可以通过蓝图或者 C++ 代码创建。AActor 是所有 Actor 的基类。\u003Cbr\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EComponents\u003C\u002Fb\u003E 用于 Actor 的子对象。相当于有一个层级。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EPawn Actor\u003C\u002Fb\u003E 的子类。可以是角色,或者是 NPC 相关的东西。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003ECharater\u003C\u002Fb\u003E 是 Pawn 和 Actor 的子类。主要用于玩家角色。加入了运动组件等。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EPlayerController\u003C\u002Fb\u003E 用于获取用户输入,并将其转换为游戏当中互动的一个类。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EAIController\u003C\u002Fb\u003E AI 的控制 \u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EGameMode\u003C\u002Fb\u003E
设置正在运行的游戏的规则\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EGameInstance\u003C\u002Fb\u003E 用于储存全局数据的。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003EGameState\u003C\u002Fb\u003E 用于跟踪游戏进度的。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cp\u003E游戏开发小记:\u003C\u002Fp\u003E\u003Cp\u003E新建 C++ 类,父类选择 Character 。\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-cpp\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F Fill out your copyright notice in the Description page of Project Settings.\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&cp\&\u003E#pragma once\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&cp\&\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\&cpf\&\u003E\&GameFramework\u002FCharacter.h\&\u003C\u002Fspan\u003E\u003Cspan class=\&cp\&\u003E\u003C\u002Fspan\u003E\n\u003Cspan class=\&cp\&\u003E#include\u003C\u002Fspan\u003E \u003Cspan class=\&cpf\&\u003E\&BaseCharacter.generated.h\&\u003C\u002Fspan\u003E\u003Cspan class=\&cp\&\u003E\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&n\&\u003EUCLASS\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EBlueprintable\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\u003Cspan class=\&k\&\u003Eclass\u003C\u002Fspan\u003E \u003Cspan class=\&nc\&\u003ETESTSHOOTER_API\u003C\u002Fspan\u003E \u003Cspan class=\&nl\&\u003EABaseCharacter\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Epublic\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EACharacter\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&n\&\u003EGENERATED_BODY\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&k\&\u003Epublic\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&n\&\u003EUPROPERTY\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EBlueprintReadWrite\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EEditAnywhere\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003ECategory\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s\&\u003E\&BaseCharacter\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&kt\&\u003Efloat\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EHealth\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E100\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\t\u003Cspan class=\&n\&\u003EUPROPERTY\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EBlueprintReadOnly\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EVisibleAnywhere\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003ECategory\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s\&\u003E\&BaseCharacter\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&kt\&\u003Ebool\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EisDead\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003Efalse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\t\u003Cspan class=\&c1\&\u003E\u002F\u002FCalculate death function(Helper)\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&k\&\u003Evirtual\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003ECalculateDead\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E();\u003C\u002Fspan\u003E\n\n\t\u003Cspan class=\&n\&\u003EUFUNCTION\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EBlueprintCallable\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003ECategory\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s\&\u003E\&BaseCharacter\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n\n\t\u003Cspan class=\&k\&\u003Evirtual\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003ECalculateHealth\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kt\&\u003Efloat\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003Edelta\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&cp\&\u003E#if WITH_EDITOR\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&k\&\u003Evirtual\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003EPostEditChangeProperty\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&n\&\u003EFPropertyChangedEvent\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E&\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EPropertyChangeEvent\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eoverride\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&cp\&\u003E#endif\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&k\&\u003Epublic\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&c1\&\u003E\u002F\u002F Sets default values for this character's properties\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&n\&\u003EABaseCharacter\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E();\u003C\u002Fspan\u003E\n\n\t\u003Cspan class=\&c1\&\u003E\u002F\u002F Called when the game starts or when spawned\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&k\&\u003Evirtual\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003EBeginPlay\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eoverride\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\t\n\t\u003Cspan class=\&c1\&\u003E\u002F\u002F Called every frame\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&k\&\u003Evirtual\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003ETick\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Efloat\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EDeltaSeconds\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eoverride\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\t\u003Cspan class=\&c1\&\u003E\u002F\u002F Called to bind functionality to input\u003C\u002Fspan\u003E\n\t\u003Cspan class=\&k\&\u003Evirtual\u003C\u002Fspan\u003E \u003Cspan class=\&kt\&\u003Evoid\u003C\u002Fspan\u003E \u003Cspan class=\&nf\&\u003ESetupPlayerInputComponent\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Eclass\u003C\u002Fspan\u003E \u003Cspan class=\&nc\&\u003EUInputComponent\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E*\u003C\u002Fspan\u003E \u003Cspan class=\&n\&\u003EInputComponent\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eoverride\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\t\n\t\n\u003Cspan class=\&p\&\u003E};\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u002F\u002F Fill out your copyright notice in the Description page of Project Settings.\n\n#include \&TestShooter.h\&\n#include \&BaseCharacter.h\&\n\n\n\u002F\u002F Sets default values\nABaseCharacter::ABaseCharacter()\n{\n\u002F\u002F Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.\nPrimaryActorTick.bCanEverTick =\n\n}\n\n\u002F\u002F Called when the game starts or when spawned\nvoid ABaseCharacter::BeginPlay()\n{\nSuper::BeginPlay();\n\n}\n\n\u002F\u002F Called every frame\nvoid ABaseCharacter::Tick( float DeltaTime )\n{\nSuper::Tick( DeltaTime );\n\n}\n\n\u002F\u002F Called to bind functionality to input\nvoid ABaseCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)\n{\nSuper::SetupPlayerInputComponent(InputComponent);\n\n}\n\n\n\nvoid ABaseCharacter::CalculateHealth(float delta) {\n\nHealth +=\nCalculateDead();\n}\n\n\n\nvoid ABaseCharacter::CalculateDead() {\nif (Health &= 0) {\nisDead =\n}\nelse\n{\nisDead =\n}\n}\n\n#if WITH_EDITOR\nvoid ABaseCharacter::PostEditChangeProperty(FPropertyChangedEvent &PropertyChangedEvent) {\nisDead =\nHealth = 100;\nSuper::PostEditChangeProperty(PropertyChangedEvent);\n\nCalculateDead();\n}\n\n#endif\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cb\u003E创建主角与游戏模式\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E鼠标右键点击 BaseCharacter 创建来自于 BaseCharacter 的蓝图类。\u003C\u002Fp\u003E\u003Cp\u003E添加一个 PlayerStart ,然后新建一个 GameMode ,在 Default Pawn Class 选择 HeroCharacter。在项目设置的 地图&模式 中Default Maps 添加自己制作的地图。Defult GameMode 选择自定义的 GameMode 。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E主角移动与旋转\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E打开 HeroCharacter 的角色蓝图,添加 输入轴MoveUp 输入轴MoveRight \u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-9ca2b7f89de1a43de519da0_b.jpg\& data-rawwidth=\&704\& data-rawheight=\&643\& class=\&origin_image zh-lightbox-thumb\& width=\&704\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-9ca2b7f89de1a43de519da0_r.jpg\&\u003E\u003C\u002Ffigure\u003E这样。Hero 就可以前后前后左右移动了。\u003C\u002Fp\u003E\u003Cp\u003E旋转添加 输入轴LookUp 输入轴LookRight \u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-106aa6aedc92ff4f5d0674_b.jpg\& data-rawwidth=\&1152\& data-rawheight=\&501\& class=\&origin_image zh-lightbox-thumb\& width=\&1152\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-106aa6aedc92ff4f5d0674_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E创建敌人蓝图\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E同样创建基于 BaseChracter 的蓝图类,命名 EnemyChracter 。\u003C\u002Fp\u003E\u003Cp\u003E打开 EnemyCharacter 的构建脚本\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-eab4b2ed5a2c1e6d21fe5_b.jpg\& data-rawwidth=\&1372\& data-rawheight=\&388\& class=\&origin_image zh-lightbox-thumb\& width=\&1372\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-eab4b2ed5a2c1e6d21fe5_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E创建敌人 AI\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E创建一个蓝图类继承自 AIController ,命名为 EnemyAI。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-61fcac4c9c560c872f2fad1_b.jpg\& data-rawwidth=\&890\& data-rawheight=\&756\& class=\&origin_image zh-lightbox-thumb\& width=\&890\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-61fcac4c9c560c872f2fad1_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 EnemyCharacter ,点击类默认图。\u003C\u002Fp\u003E\u003Cp\u003E在 Pawn 下有一个 AI Contrller Class ,选择 EnemyAI。将 EnemyCharacter 拖动到场景中。但是还没有添加导航网格。添加 Nav Mesh Bounds Volume 到场景中。使其能覆盖可运动的场地。现在敌人可以追逐你了。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E创建子弹和武器\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E新建一个蓝图类继承自 Actor ,命名为 Projectile。添加一个 Sphere Collision(碰撞体),命名为 ProjectileCollision 。添加一个球体,命名为 LaserMesh 。碰撞预设值改为没有碰撞。拉长,压扁。\u003C\u002Fp\u003E\u003Cp\u003E新建一个材质,命名为 ProjectileMaterial。Blend Mode 改为 Additive。Shading Model 选择 Unlit 。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-3ba4fdce72d6e2df2b574540_b.jpg\& data-rawwidth=\&721\& data-rawheight=\&698\& class=\&origin_image zh-lightbox-thumb\& width=\&721\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-3ba4fdce72d6e2df2b574540_r.jpg\&\u003E\u003C\u002Ffigure\u003E然后将 Projectile 改为做好的 Materials。\u003C\u002Fp\u003E\u003Cp\u003E在Projectile 添加 ProjectileMovement ,将 Initial Speed 改为 1200。Projectile Gravity Scale 改为 0。\u003C\u002Fp\u003E\u003Cp\u003E创建一个武器类,继承自 Actor ,命名为 Weapon。添加一个 Mesh ,命名为 GunMesh 。指定一个 Mesh。添加一个 Arrow ,命名为 ProjectileSpawnPoint ,覆到 GunMesh 下面。然后在视图中对上枪口。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E开枪逻辑实现\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-a70ff7a279a1b57b4e3e_b.jpg\& data-rawwidth=\&1204\& data-rawheight=\&426\& class=\&origin_image zh-lightbox-thumb\& width=\&1204\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-a70ff7a279a1b57b4e3e_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-5a4a98e7ccfd2e1b8e2d49_b.jpg\& data-rawwidth=\&1424\& data-rawheight=\&543\& class=\&origin_image zh-lightbox-thumb\& width=\&1424\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-5a4a98e7ccfd2e1b8e2d49_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 HeroCharacter ,添加 Arrow,命名为 GunTemp。然后打开事件图表。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-f602b36ed44ae3ac7ede_b.jpg\& data-rawwidth=\&1404\& data-rawheight=\&390\& class=\&origin_image zh-lightbox-thumb\& width=\&1404\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-f602b36ed44ae3ac7ede_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-09194afcd3cf3fe6f70fec7ac90b0525_b.jpg\& data-rawwidth=\&974\& data-rawheight=\&225\& class=\&origin_image zh-lightbox-thumb\& width=\&974\& data-original=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-09194afcd3cf3fe6f70fec7ac90b0525_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E实现对敌人的伤害\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E创建一个蓝图接口,命名为 IDamageable。打开,重命名函数 Affect Health。添加一个输入值。浮点型的 Delta 。打开敌人的蓝图,点击类设置。添加刚刚的接口。打开 Projectile ,点击 ProjectileCollision。修改碰撞预设值为 OverlapOnlyPawn 。回到事件蓝图。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-e15fed61a_b.jpg\& data-rawwidth=\&757\& data-rawheight=\&289\& class=\&origin_image zh-lightbox-thumb\& width=\&757\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-e15fed61a_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 HeroCharacter,添加一个 Tags ,命名为 Friendly。然后继续编辑 Projectile。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-e1c3ee2f3a4fa853ef2a0f8f85b31b26_b.jpg\& data-rawwidth=\&1349\& data-rawheight=\&854\& class=\&origin_image zh-lightbox-thumb\& width=\&1349\& data-original=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-e1c3ee2f3a4fa853ef2a0f8f85b31b26_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E实现对主角的伤害\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E打开 HeroCharacter 的角色蓝图。在类设置中添加 IDamageable 接口。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-ac6eaf54ec05abdca440cbeb7d4bb64e_b.jpg\& data-rawwidth=\&1346\& data-rawheight=\&377\& class=\&origin_image zh-lightbox-thumb\& width=\&1346\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-ac6eaf54ec05abdca440cbeb7d4bb64e_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 EnemyCharacter ,添加 Box Collision ,命名为 DamageVolume。摆放到如下位置:\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-3b531c9f9356cdb74a63_b.jpg\& data-rawwidth=\&604\& data-rawheight=\&592\& class=\&origin_image zh-lightbox-thumb\& width=\&604\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-3b531c9f9356cdb74a63_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cp\u003E当玩家走进这个区域,进行扣血的操作。\u003C\u002Fp\u003E\u003Cp\u003E回到事件蓝图。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-445fd2b2f3fec_b.jpg\& data-rawwidth=\&1263\& data-rawheight=\&742\& class=\&origin_image zh-lightbox-thumb\& width=\&1263\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-445fd2b2f3fec_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E玩家重生与敌人生成\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E打开 GameMode 事件蓝图\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-b71efbaf6f88fce895cf_b.jpg\& data-rawwidth=\&1525\& data-rawheight=\&529\& class=\&origin_image zh-lightbox-thumb\& width=\&1525\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-b71efbaf6f88fce895cf_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 HeroCharacter 事件蓝图。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-d2a147efc975a844b40145fcf610ac52_b.jpg\& data-rawwidth=\&1439\& data-rawheight=\&316\& class=\&origin_image zh-lightbox-thumb\& width=\&1439\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-d2a147efc975a844b40145fcf610ac52_r.jpg\&\u003E\u003C\u002Ffigure\u003E新建蓝图类,添加一个 Actor ,命名为 EnemySpawner。添加一个 BoxCollision,命名为 SpawnVolume。将其放在场景的上空。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-0798439aedd58b3c8f5f7_b.jpg\& data-rawwidth=\&1473\& data-rawheight=\&752\& class=\&origin_image zh-lightbox-thumb\& width=\&1473\& data-original=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-0798439aedd58b3c8f5f7_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 GameMode\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-a665dbd8b6ff3ec45332d_b.jpg\& data-rawwidth=\&1522\& data-rawheight=\&280\& class=\&origin_image zh-lightbox-thumb\& width=\&1522\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-a665dbd8b6ff3ec45332d_r.jpg\&\u003E\u003C\u002Ffigure\u003E此时发现子弹不会被销毁,打开 Projectile ,修改 Initial Life Span 值为 1.5。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E玩家的动画制作\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E添加混合动画,命名为 HeroBlend。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-e57dc4ed3fd_b.jpg\& data-rawwidth=\&1347\& data-rawheight=\&475\& class=\&origin_image zh-lightbox-thumb\& width=\&1347\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-e57dc4ed3fd_r.jpg\&\u003E\u003C\u002Ffigure\u003E新建动画蓝图\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-b0b0cd644bfd_b.jpg\& data-rawwidth=\&1219\& data-rawheight=\&557\& class=\&origin_image zh-lightbox-thumb\& width=\&1219\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-b0b0cd644bfd_r.jpg\&\u003E\u003C\u002Ffigure\u003E将 HeroCharacter 的 Anim Blueprint Generates Class 改为 CharacterAnimBP。\u003C\u002Fp\u003E\u003Cp\u003E打开 CharacterAnimBP\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-de44a290b48e72e04ba4d4eb4cc440fd_b.jpg\& data-rawwidth=\&902\& data-rawheight=\&383\& class=\&origin_image zh-lightbox-thumb\& width=\&902\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-de44a290b48e72e04ba4d4eb4cc440fd_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-92feb98447cbfdfe3fcc308b8cef14bf_b.jpg\& data-rawwidth=\&801\& data-rawheight=\&333\& class=\&origin_image zh-lightbox-thumb\& width=\&801\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-92feb98447cbfdfe3fcc308b8cef14bf_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-61c8d4e2afbbb_b.jpg\& data-rawwidth=\&1029\& data-rawheight=\&456\& class=\&origin_image zh-lightbox-thumb\& width=\&1029\& data-original=\&https:\u002F\u002Fpic3.zhimg.com\u002Fv2-61c8d4e2afbbb_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-cd86bad49f1c70ebdf6b0b3cbd499321_b.jpg\& data-rawwidth=\&1005\& data-rawheight=\&490\& class=\&origin_image zh-lightbox-thumb\& width=\&1005\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-cd86bad49f1c70ebdf6b0b3cbd499321_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-b97e0a92c2a4beb41ce0_b.jpg\& data-rawwidth=\&1427\& data-rawheight=\&462\& class=\&origin_image zh-lightbox-thumb\& width=\&1427\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-b97e0a92c2a4beb41ce0_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-b6bfc3a7c9f3cc968031e_b.jpg\& data-rawwidth=\&1365\& data-rawheight=\&435\& class=\&origin_image zh-lightbox-thumb\& width=\&1365\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-b6bfc3a7c9f3cc968031e_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E武器的附加\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E在 hand_r 里添加一个插槽,添加枪的资源。将 HeroCharacter 中的 GunTemp 改为 Mesh 。在 AttachActor ToComponent 中的 In Socket Name 改为 GunSocket。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E敌人动画的添加\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E新建混合空间,命名 EnemyBlend。创建一个 CharacterAnimBP 的子蓝图,命名 EnemyAnimBP。混合空间播放换为 EnemyBlend。然后点击 EnemyCharacter 的 Mesh,Anim Blueprint Generated Class 选择 EnemyAnimBP。\u003C\u002Fp\u003E\u003Cp\u003E打开 EnemyCharacter 的事件图表。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-b41d79fd8163d8bcd3d5a3_b.jpg\& data-rawwidth=\&1370\& data-rawheight=\&513\& class=\&origin_image zh-lightbox-thumb\& width=\&1370\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-b41d79fd8163d8bcd3d5a3_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-b931f7d38c973f0ba02f4f3286fdd936_b.jpg\& data-rawwidth=\&1318\& data-rawheight=\&402\& class=\&origin_image zh-lightbox-thumb\& width=\&1318\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-b931f7d38c973f0ba02f4f3286fdd936_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cb\u003E制作 UI\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E新建 用户界面-&空间蓝图,命名为 HUD。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-0c07a1a227bc0e67c55e_b.jpg\& data-rawwidth=\&1493\& data-rawheight=\&650\& class=\&origin_image zh-lightbox-thumb\& width=\&1493\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-0c07a1a227bc0e67c55e_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-961eb0c6afd75aadaaed9_b.jpg\& data-rawwidth=\&1035\& data-rawheight=\&428\& class=\&origin_image zh-lightbox-thumb\& width=\&1035\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-961eb0c6afd75aadaaed9_r.jpg\&\u003E\u003C\u002Ffigure\u003E给 Progress 创建绑定,Health Bar。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-ee5ecac9d2272adb8d2b_b.jpg\& data-rawwidth=\&1158\& data-rawheight=\&621\& class=\&origin_image zh-lightbox-thumb\& width=\&1158\& data-original=\&https:\u002F\u002Fpic1.zhimg.com\u002Fv2-ee5ecac9d2272adb8d2b_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-8ffca06e22d_b.jpg\& data-rawwidth=\&1364\& data-rawheight=\&431\& class=\&origin_image zh-lightbox-thumb\& width=\&1364\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-8ffca06e22d_r.jpg\&\u003E\u003C\u002Ffigure\u003E打开 GameMode\u003C\u002Fp\u003E\u003Cp\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-c09c7da38c95f6b8b6c4d79_b.jpg\& data-rawwidth=\&649\& data-rawheight=\&248\& class=\&origin_image zh-lightbox-thumb\& width=\&649\& data-original=\&https:\u002F\u002Fpic4.zhimg.com\u002Fv2-c09c7da38c95f6b8b6c4d79_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cfigure\u003E\u003Cimg src=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-901a6cfbcc69aeab5b0bb382_b.jpg\& data-rawwidth=\&1300\& data-rawheight=\&521\& class=\&origin_image zh-lightbox-thumb\& width=\&1300\& data-original=\&https:\u002F\u002Fpic2.zhimg.com\u002Fv2-901a6cfbcc69aeab5b0bb382_r.jpg\&\u00

我要回帖

更多关于 无法勾选 旧版组件 的文章

 

随机推荐