马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
一.项目简介
《Tank_Battle》是一款基于 Unity 引擎开发的 3D 双人对战坦克游戏。玩家在游戏中操控各自的坦克,通过机动移动、旋转和发射子弹等利用,睁开剧烈的对战,旨在摧毁对方坦克以得到胜利。该项目团结了丰富的游戏元素和交互机制,为玩家带来沉醉式的游戏体验。
游戏画面如下:
Tank_battle
二.创建场景
1.创建3D工程(定名为Tank_Battle)
2.导入unity_package(资源包)到Project窗口中(资源在素材内里)
3.将文件夹Prefab中levelart(场景)拖入到hierarchy窗口中
4.删除场景自带的直射光,由于levelart中自带了直射光
5.调治场景光线:Window——Reddering——Lighting——Environment(source光源调成color颜色,颜色调成和环境贴合的颜色)
6.Main camera改变天空场景颜色
三.添加坦克(加拖尾殊效)
1.把models中Tank拖放到Hierarchy视图中
2.把prefab中的DustTrall拖入到Tank上,复制一个,选中两个拖尾,分别将两个拖尾移动到轮子履带处
3.拖尾位置如下
4.给tank添加Box collider组件
5.调治collider的巨细
6.把tank酿成prefab,直接把tank拖到Projectors——Prefab文件夹中(为了反面坦克多了同一管理)
四.控制坦克前后移动
1.创建控制坦克移动的脚本并定名为Tank_ Move(记得创建一个Scripst文件夹同一管理脚本)
2.选择Tank,添加刚体组件Rigidbody
3.进入Tank_Move脚本
4.获取Tank自己Rigidbody组件
4.1创建刚体变量,生存
- public class TankMove : MonoBehaviour
- {
- public Rigidbody Tank_body;//创建刚体变量接受Tank的刚体
- // Start is called before the first frame update
- void Start()
- {
-
- }
- // Update is called once per frame
- void Update()
- {
-
- }
- }
复制代码 4.2把脚本拖放到Tank身上,然后把Tank脚本的Tank_body变量指定为Tank自己的Rigidbody
5.按键控制tank前后移动
5.1按键ws控制移动
5.2检测按键ws按下并生存按下的返回值
Input.GetAxisRaw();作用是:检测是否有按键按下,并返回float值
"Vertical"作用是:竖直方向
5.3按键使得坦克向前大概向后移动
transform.forward 的寄义
方向表现:它是一个三维向量(Vector3 范例),指向游戏对象所面向的正火线。这个方向是相对于游戏对象的旋转而言的,当游戏对象的旋转发生改变时,transform.forward 的方向也会随之改变。
五.控制坦克旋转
1.按键ad控制旋转
2.检测按键ad按下并生存按下的返回值
3.绕Y轴移动
这行代码的重要功能是设置坦克刚体(Tank_body)的角速率,从而让坦克绕着轴举行旋转。旋转的轴是游戏对象自身的向上方向(transform.up),即Y轴,旋转的速率由 r 和 TankRotate_Speed 共同决定。
4.完备代码显现
六.控制两辆坦克(实现双人一起玩)
1.打开Edit——Projectsettings——input Manger
2.包管ad只控制Player1的旋转,左右箭头只控制Player2的旋转
2.1光标放到Horizontal上,右击创建两个新的Horizontal,分别定名为Horizontal_Player1,Horizontal_Player2
2.2玩家一删除下图圈出来的内容,表现取消左右箭头控制进步
2.3玩家二删除下图圈出来的内容,表现取消ad按键控制旋转
3.包管ws只控制Player1的进步退却,上下箭头只控制Player2的进步退却
3.1光标放到Vertical上,右击创建两个新的Vertical,分别定名为Vertical_Player1,Vertical_Player2
3.2玩家一删除下图圈出来的内容,表现取消上下箭头控制进步
3.3玩家二删除下图圈出来的内容,表现取消ws按键控制旋转
七.控制坦克发射子弹
1.将子弹创建出来,并实例化
1.1将子弹素材拖入到Hierarchy中,并拖入Prefab成为预制体,并添加胶囊碰撞器
1.2修改碰撞体巨细(记得按下图利用,肯定要改成z轴)
1.3实例化子弹——确定位置。创建一个空物体,用来确定子弹发射位置,空物体是倾斜的(由于炮管是倾斜的),定名为fireposition
2.添加子弹攻击脚本Tank_Shoot——实例化子弹
2.1创建脚本
2.2创建变量担当位置,同时选中每次创建的子弹
- public Transform firePosition;//接受发射子弹的位置物体
- public GameObject ShellPrefab;//接受每次创建的实例化子弹
复制代码 2.3把脚本拖到发射位置物体上,然后把发射位置和发射的子弹预制体选中
2.4把发射位置物体,拖到Tank物体上,作为其子对象,如许就可以包管相对位置稳固了
2.5空格键控制子弹发射
2.6控制子弹飞行速率
八.子弹爆炸结果
1.创建子弹脚本Sheet
2.担当爆炸结果的预制体
3.当子弹触发器触碰到其他物体时,触发爆炸结果
4.我增长了一个开火也可以有爆炸结果,模仿后坐力很大
九.控制子弹造成伤害
1.给tank加tag标签,区分子弹是否触碰到了tank
2.写脚本——tank受到伤害处理惩罚的脚本
- public class Tank_health : MonoBehaviour
- {
- public int hp = 100;//坦克血量
- public GameObject Tankbaozha;//坦克爆炸效果
- public AudioSource TankbaozhaAudioSource;
- // Start is called before the first frame update
- void Start()
- {
-
- }
- // Update is called once per frame
- void Update()
- {
-
- }
- void HurtHealthy()
- {
- if (hp < 0)
- {
- return;
- }
- hp -= Random.Range(10, 20);//伤害是随机的 10 20
- if (hp < 0)//坦克没了
- {
- TankbaozhaAudioSource.Play();
- GameObject.Instantiate(Tankbaozha,transform.position+Vector3.up,transform.rotation);
- GameObject.Destroy(this.gameObject);
- #if UNITY_EDITOR
- UnityEditor.EditorApplication.isPlaying = false;
- #else
- Application.Quit();
- #endif
- }
- }
复制代码 3.tank触发到tank,调用2中天生的脚本
- public void OnTriggerEnter(Collider other)
- {
- if (SheelExplosionPrefab != null)
- {
- GameObject.Instantiate(SheelExplosionPrefab, transform.position, transform.rotation);
- }
- if(other.tag=="Tank")
- {
- other.SendMessage("HurtHealthy");//即调用的方法
- }
- }
复制代码
十.相机跟随
原理:相机与两坦克的中心保持肯定的向量关系,同时尚有近大远小的视觉结果
1.算出两坦克的中心点与摄像机坐标的向量差。
2.包管摄像机始终与中心点有个类似向量差
3.当坦克间距变小时,摄像头视角变小;反之,摄像头变大
十一.添加音效,音乐
1.配景音乐
(1)创建一个空物体,定名为:Music
(2)在空物体上添加组件audio source
(3)在组件上添加配景音乐
(4)举行底子设置即可
2.子弹音效:每次发射都会启动
原理:一样的添加audio source组件用来存储音效,每次在实例化子弹的时间,启动音效
十二.标题
1.大概出现的标题1:Assembly-CSharp-Editor渲染函数老旧逾期了。
办理方案:更换函数,下面是更换之后的代码:(复制粘贴即可)
- using System;
- using UnityEditor;
- using UnityEngine;
- namespace UnityStandardAssets.ImageEffects
- {
- [CustomEditor(typeof(ColorCorrectionLookup))]
- class ColorCorrectionLookupEditor : Editor
- {
- SerializedObject serObj;
- void OnEnable()
- {
- serObj = new SerializedObject(target);
- }
- private Texture2D tempClutTex2D;
- public override void OnInspectorGUI()
- {
- serObj.Update();
- EditorGUILayout.LabelField("Converts textures into color lookup volumes (for grading)", EditorStyles.miniLabel);
- //EditorGUILayout.LabelField("Change Lookup Texture (LUT):");
- //EditorGUILayout.BeginHorizontal ();
- //Rect r = GUILayoutUtility.GetAspectRect(1.0ff);
- Rect r; Texture2D t;
- //EditorGUILayout.Space();
- tempClutTex2D = EditorGUILayout.ObjectField(" Based on", tempClutTex2D, typeof(Texture2D), false) as Texture2D;
- if (tempClutTex2D == null)
- {
- t = AssetDatabase.LoadMainAssetAtPath(((ColorCorrectionLookup)target).basedOnTempTex) as Texture2D;
- if (t) tempClutTex2D = t;
- }
- Texture2D tex = tempClutTex2D;
- if (tex && (target as ColorCorrectionLookup).basedOnTempTex != AssetDatabase.GetAssetPath(tex))
- {
- EditorGUILayout.Separator();
- if (!(target as ColorCorrectionLookup).ValidDimensions(tex))
- {
- EditorGUILayout.HelpBox("Invalid texture dimensions!\nPick another texture or adjust dimension to e.g. 256x16.", MessageType.Warning);
- }
- else if (GUILayout.Button("Convert and Apply"))
- {
- string path = AssetDatabase.GetAssetPath(tex);
- TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
- bool doImport = textureImporter.isReadable == false;
- if (textureImporter.mipmapEnabled == true)
- {
- doImport = true;
- }
- // 修改:检查纹理压缩格式
- if (textureImporter.textureCompression != TextureImporterCompression.Uncompressed)
- {
- doImport = true;
- }
- if (doImport)
- {
- textureImporter.isReadable = true;
- textureImporter.mipmapEnabled = false;
- // 修改:设置纹理压缩格式为无压缩
- textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
- AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
- //tex = AssetDatabase.LoadMainAssetAtPath(path);
- }
- (target as ColorCorrectionLookup).Convert(tex, path);
- }
- }
- if ((target as ColorCorrectionLookup).basedOnTempTex != "")
- {
- EditorGUILayout.HelpBox("Using " + (target as ColorCorrectionLookup).basedOnTempTex, MessageType.Info);
- t = AssetDatabase.LoadMainAssetAtPath(((ColorCorrectionLookup)target).basedOnTempTex) as Texture2D;
- if (t)
- {
- r = GUILayoutUtility.GetLastRect();
- r = GUILayoutUtility.GetRect(r.width, 20);
- r.x += r.width * 0.05f / 2.0f;
- r.width *= 0.95f;
- GUI.DrawTexture(r, t);
- GUILayoutUtility.GetRect(r.width, 4);
- }
- }
- //EditorGUILayout.EndHorizontal ();
- serObj.ApplyModifiedProperties();
- }
- }
- }
复制代码
十三.结语
《Tank_Battle》不但是一款具有娱乐性的游戏,也是一个良好的 Unity 开发实践项目。对于初学者来说,它展示了怎样使用 Unity 引擎举行场景搭建、对象控制、碰撞检测和殊效实现等底子开发技能;对于有肯定履历的开发者,也可以从中获取关于双人对战游戏操持和实现的思绪和方法。同时,项目还提供了大概出现标题标办理方案,有助于开发者在碰到类似标题时快速办理。
|