视频链接为:大学生设计游戏的精神状态_哔哩哔哩_bilibili
代码仓库链接为:clement2048/shoot_game (github.com)
1.地形
使用地形组件,上面有草、树;
在Hierarchy中新建一个3D对象Terrain,可以在右边的Inspector中的Terrain来添加临近地形,绘制地形,绘制树以及地形的细节
使用地形组件,上面有草、树
这里使用的树的模型为:unity商城里的Free_Trees
地形细节(草)的模型为:随便找的一个草字的图片作为贴图
结果如下:
这样就能在地图中出现草和树了。
2.天空盒
天空可随时间变化 或 按特定按键切换天空盒;
以下代码可以实现时间变化或按特定按键切换天空盒,该代码主要实现了时间变化(5秒)以及特定按键(空格)来实现切换天空盒。
这里需要在型添加的
using System.Collections;
using UnityEngine;
public class SkyboxSwitcher : MonoBehaviour
{
public Material[] skyboxes;
private int currentSkyboxIndex = 0;
public float timeInterval = 5f; // 切换天空盒的时间间隔
private Coroutine switchSkyboxCoroutine;
void Start()
{
RenderSettings.skybox = skyboxes[currentSkyboxIndex];
StartSwitchSkyboxCoroutine();
}
void Update()
{
// 示例:按下空格键切换天空盒并重置时间间隔
if (Input.GetKeyDown(KeyCode.Space))
{
SwitchSkybox();
ResetSwitchSkyboxCoroutine();
}
}
void SwitchSkybox()
{
currentSkyboxIndex = (currentSkyboxIndex + 1) % skyboxes.Length;
RenderSettings.skybox = skyboxes[currentSkyboxIndex];
}
void StartSwitchSkyboxCoroutine()
{
if (switchSkyboxCoroutine != null)
StopCoroutine(switchSkyboxCoroutine);
switchSkyboxCoroutine = StartCoroutine(SwitchSkyboxWithTimeInterval());
}
void ResetSwitchSkyboxCoroutine()
{
StartSwitchSkyboxCoroutine();
}
IEnumerator SwitchSkyboxWithTimeInterval()
{
while (true)
{
yield return new WaitForSeconds(timeInterval);
// 切换天空盒
SwitchSkybox();
}
}
}
3.固定靶
有一个以上固定的靶标
使用的模型为:Lowpoly training dummy
模型如下:
4.运动靶
有一个以上运动靶标,运动轨迹,速度使用动画控制,
运动靶直接使用一个球体作为运动靶,图片如下:
这里直接使用了C#代码来实现了运动靶
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class targetMovement : MonoBehaviour
{
// Start is called before the first frame update
public float speed = 0.05f; // 物体的移动速度
public float width = 2f; // 矩形的宽度
public float height = 2f; // 矩形的高度
private Vector3 startPosition; // 初始位置
private float x;
private float y;
void Start()
{
startPosition = transform.position; // 获取初始位置
}
void Update()
{
x = Mathf.Sin(Time.time * speed) * width; // 按照时间和速度计算x坐标
y = Mathf.Cos(Time.time * speed) * height; // 按照时间和速度计算y坐标
transform.position = startPosition + new Vector3(x, y, 0); // 更新物体的位置
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("arrow")) // 检查碰撞对象的标签是否为"Target"
{
Debug.Log("Arrow hit the target!");
uiscore.score++;
// 获取碰撞对象的 Rigidbody 组件
Destroy(collision.gameObject.GetComponent<Rigidbody>());
Transform targetRigidbody=collision.gameObject.GetComponent<Transform>();
targetRigidbody.transform.SetParent(transform, true);
// 创建 FixedJoint 组件并将其连接到箭和靶子上
}
}
}
5.射击位
目标:地图上应标记若干射击位,仅在射击位附近可以拉弓射击,每个位置有 n 次机会;
为了实现射击位,这里利用了许多的正方体来作为射击区域,并且射击区域的碰撞体可以作为触发器。当人物进入区域后会触发代码,并且在屏幕中显示剩余射击次数。默认为5次
实现效果如下:
只要进入该区域就会进行触发。触发器的相关代码在github仓库中可见。
6.驽弓动画
目标:支持蓄力半拉弓,然后 hold,择机 shoot;
这里使用了animation controller,具体controller可以通过代码仓库来查看。
7.游走
要求:玩家的驽弓可在地图上游走,不能碰上树和靶标等障碍
这里直接在弩弓、树和靶标加入碰撞体,其中树的碰撞体为椭球碰撞体,而靶标的碰撞体用的是网状的碰撞体,具体的属性和组件可以查看代码仓库详细查看。
8.碰撞与计分
要求:在射击位,射中靶标的相应分数,规则自定;
规则为射中移动靶得2分
射中固定靶得1分。
需要在箭上添加碰撞体和刚体。
具体代码还是看仓库吧。