游戏实现偏向简单,源码太大,有需要直接留邮箱
一、前期准备
“
了解基础的项目创建
材质包使用
设计地形、菲涅尔水面、瀑布效果、喷泉效果、树木效果、利用Shuriken粒子系统,制作和场景协调的粒子动画、天空盒
、光照系统、音效系统 。
”
c#代码基础编写:角色移动控制、相机跟随、对象创建与销毁。
预制体创建
游戏UI待加入
游戏玩法设计
相机漫游展示岛屿 -- 进入游戏 -- 游戏结束
“游戏背景:在一个星球的一座孤岛上,一个宇航员独自探索。 游戏流程:箱盒式,固定一个封闭的路线,游戏引导玩家操控player走完整个流程。 游戏玩法:玩家通过捡不同的道具产生不同的体形改变,用不同的视角去探索这个峡谷。 游戏特色:
”
风景设计
道具改变玩家体形进而改变视角
地图风格从 -- 荒岛海滩 -- 雨林 -- 浮空岛 -- 黑雾 - 火焰 -- 沙漠的变化(当然没做很细致)
简单实现了菜单相机漫游和道具拾取以及文字碰撞摧毁;
界面优化
在Windows等图形化操作系统上,熟练地使用菜单、图标、快捷键等,将会极大提升工作效率。因此,要认识一个软件,学会熟练使用他们,就必须先认识软件的界面。 先点击菜单栏的Window——Layouts——2by3,设置成如下的界面,方便我们了解各个窗口。
但还是选择了经典界面显示的资源目录更详细
项目概述
目录: 素材来自:unity商城,代码自己编写部分参考百度csdn,音效来自爱给网;
游戏效果:
二、项目创建流程
1. 创建项目
image.png
2. 导入材质包
image.png
3. 创建基本地形
创建基本地形+天空盒子
创建基本地形
4. 地形添加细节
添加天空倒影+水面效果
“营造岛屿效果
”
添加动态的草--导入材质包--导入草预设体
搭建游戏主场景
5. 加入角色
导入模型
添加角色控制器
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour
{
private Animator anim;
private CharacterController controller;
private int cnt;
public AudioClip audioSource;
public float speed = 600.0f;
public float turnSpeed = 400.0f;
private Vector3 moveDirection = Vector3.zero;
public float gravity = 20.0f;
//AudioSource组件
private AudioSource _mAudioSource;
void Start()
{
//获得AudioSource组件
_mAudioSource = GetComponent<AudioSource>();
_mAudioSource.clip = audioSource;
controller = GetComponent<CharacterController>();
anim = gameObject.GetComponentInChildren<Animator>();
cnt = 0;
}
void Update()
{
if (Input.GetKey("w"))
{
if (_mAudioSource.isPlaying == false && cnt % 60 == 0)
{
_mAudioSource.Play();
}
anim.SetInteger("AnimationPar", 1);
cnt++;
}
else
{
_mAudioSource.Stop();
anim.SetInteger("AnimationPar", 0);
}
if (controller.isGrounded)
{
moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;
}
float turn = Input.GetAxis("Horizontal");
transform.Rotate(0, turn * turnSpeed * Time.deltaTime, 0);
controller.Move(moveDirection * Time.deltaTime);
moveDirection.y -= gravity * Time.deltaTime;
}
}
绑定骨骼动画
6. 加入相机跟随
“加入相机跟随+鼠标移动切换视角
”
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonCamera : MonoBehaviour
{
private const float Y_ANGLE_MIN = 0.0f;
private const float Y_ANGLE_MAX = 50.0f;
public Transform lookAt;
public Transform camTransform;
public float distance = 5.0f;
private float currentX = 0.0f;
private float currentY = 45.0f;
private float sensitivityX = 20.0f;
private float sensitivityY = 20.0f;
private void Start()
{
camTransform = transform;
}
private void Update()
{
currentX += Input.GetAxis("Mouse X");
currentY += Input.GetAxis("Mouse Y");
currentY = Mathf.Clamp(currentY, Y_ANGLE_MIN, Y_ANGLE_MAX);
}
private void LateUpdate()
{
Vector3 dir = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
camTransform.position = lookAt.position + rotation * dir;
camTransform.LookAt(lookAt.position);
}
}
7. 设计游戏玩法
设计UI与开始菜单
“”
image.png
“原理:设计两个摄像机 第一个摄像机采用漫游旋转的方式 并且在前面加一个3Dtext 同时监听键盘,按键就摧毁它 此时视角就跳到了第二个摄像机上了。
”
1. 设置游戏边界,创建空气墙
规划角色的活动区域 ,其实就是建立空物体Empty,然后给它加上特定位置和大小的BoxCollider ,这样刚体碰到这个透明的东西,就真的像碰到一堵墙一样。
添加游戏元素
设计碰撞效果检测
“通过tag区分碰撞物体,给玩家添加不同效果
”
“big1 : 变大一倍 big2: 变大两倍 little1: 缩小一倍 little2: 缩小两倍
”
private void OnCollisionEnter(Collision collision)
{
print(collision.collider.name);
print(collision.collider.tag);
if (collision.collider.tag == "del")
{
GameObject a = GameObject.FindGameObjectWithTag("del"); //通过Tag获得物体
gameObject.GetComponent<Transform>().localScale = new Vector3(10, 10, 10);
Destroy(a);
}
if (collision.collider.tag == "big1")
{
GameObject a = GameObject.FindGameObjectWithTag(collision.collider.tag); //通过Tag获得物体
//变小
gameObject.GetComponent<Transform>().localScale = new Vector3(30, 30, 30);
Destroy(a);
GameObject b = GameObject.FindGameObjectWithTag("MainCamera"); //通过Tag获
b.GetComponent<ThirdPersonCamera>().distance = 9;
GameObject c = GameObject.FindGameObjectWithTag("MainPlayer"); //通过Tag获
c.GetComponent<Player>().speed = 15;
_mAudioSource.clip = change;
_mAudioSource.Play();
}
else if (collision.collider.tag == "little1")
{
GameObject a = GameObject.FindGameObjectWithTag(collision.collider.tag); //通过Tag获得物体
//变小
gameObject.GetComponent<Transform>().localScale = new Vector3(5, 5, 5);
Destroy(a);
GameObject b = GameObject.FindGameObjectWithTag("MainCamera"); //通过Tag获
b.GetComponent<ThirdPersonCamera>().distance = 5;
GameObject c = GameObject.FindGameObjectWithTag("MainPlayer"); //通过Tag获
c.GetComponent<Player>().speed = 20;
_mAudioSource.clip = change;
_mAudioSource.Play();
}
else if (collision.collider.tag == "little2")
{
GameObject a = GameObject.FindGameObjectWithTag(collision.collider.tag); //通过Tag获得物体
//变小
gameObject.GetComponent<Transform>().localScale = new Vector3(2, 2, 2);
Destroy(a);
GameObject b = GameObject.FindGameObjectWithTag("MainCamera"); //通过Tag获
b.GetComponent<ThirdPersonCamera>().distance = 4;
GameObject c = GameObject.FindGameObjectWithTag("MainPlayer"); //通过Tag获
c.GetComponent<Player>().speed = 5;
_mAudioSource.clip = change;
_mAudioSource.Play();
}
else if (collision.collider.tag == "big2")
{
GameObject a = GameObject.FindGameObjectWithTag(collision.collider.tag); //通过Tag获得物体
//变小
gameObject.GetComponent<Transform>().localScale = new Vector3(50, 50, 50);
Destroy(a);
GameObject b = GameObject.FindGameObjectWithTag("MainCamera"); //通过Tag获
b.GetComponent<ThirdPersonCamera>().distance = 20;
GameObject c = GameObject.FindGameObjectWithTag("MainPlayer"); //通过Tag获
c.GetComponent<Player>().speed = 20;
_mAudioSource.clip = change;
_mAudioSource.Play();
}
//捡到蘑菇/银币
if (collision.collider.name != "Terrain" && collision.collider.name != "player")
{
Destroy(collision.gameObject);
if (collision.collider.tag == "coin")
{
_mAudioSource.clip = audioSource;
_mAudioSource.Play();
}
}
}
给相机添加碰撞器
“防止卡视野
”
添加游戏提示
添加魔镜|传送门 用户抵达魔镜就用碰撞器检测改变玩家体形
8. 添加用户环境交互
1. 添加环境音效
image.png
1. 添加脚步声
if (Input.GetKey("w"))
{
if (_mAudioSource.isPlaying == false && cnt % 60 == 0)
{
_mAudioSource.Play();
}
anim.SetInteger("AnimationPar", 1);
cnt++;
}
else
{
_mAudioSource.Stop();
anim.SetInteger("AnimationPar", 0);
}
添加游戏粒子效果和下雨效果
喷泉效果
瀑布效果
添加游戏logo
9.游戏模块
-
遗迹
image.png
-
树林
-
image.png
-
秘境
-
-
黑雾陡崖
-
-
火焰石墙
-
-
浮岛遗迹
-
image.png image.png image.png image.png
10. 游戏打包发布
-
file - build- settings
-
add open secens添加场景
打包完成
三、项目总结经验
遇到问题及解决
-
游戏打包后tag混乱,导致触发不同的tag没有产生相应的效果
解决方法: 参考自———————————————— 版权声明:本文为CSDN博主「网络华佗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:Unity打包后,tag值混乱导入碰撞触发失效_GenJi0的博客-CSDN博客
“这是正常的tag标签值,但如果使用的时候,其中一个使用不到或者不想用了,我们会把它删掉,但是删掉后,tag值显示为 (Removed)就是这个问题; **因为打包的时候信息保存的是tag列表信息,而不是tag的字符串名字。如果tag列表中有(Removed),那么打包保存的时候会把后面的tag往前移。这样就导致后面的tag位置索引变了。运行的时候加载出来的物体的tag就会发生变化。那么tag值来判断的触发或碰撞条件将会失效或者变化。
”
“这种情况下 ,只要把 unity客户端关闭重新打开 ,tag值就会自动补全Removed 就可以打包运行了**
”
收获
测试自己独立写了一个游戏。 自己独立实现开头的"动画 "和一些运镜,把自己的一些想法加到了游戏里面。但搭场景实在太花时间了,导致后面游戏玩法就没太做。最后还是收货挺大吧。