前言
本文为使用 Classical Crossbow 等资源完成的第一人称射箭游戏开发技术博客,视频演示在文章末尾。
实验目标
基础分(2分):有博客;
1-3分钟视频(2分):视频呈现游戏主要游玩过程;
地形(2分):使用地形组件,上面有草、树;
天空盒(2分):使用天空盒,天空可随玩家位置 或 时间变化 或 按特定按键切换天空盒;
固定靶(2分):有一个以上固定的靶标;
运动靶(2分):有一个以上运动靶标,运动轨迹,速度使用动画控制;
射击位(2分):地图上应标记若干射击位,仅在射击位附近可以拉弓射击,每个位置有 n 次机会;
驽弓动画(2分):支持蓄力半拉弓,然后 hold,择机 shoot;
游走(2分):玩家的驽弓可在地图上游走,不能碰上树和靶标等障碍;
碰撞与计分(2分):在射击位,射中靶标的相应分数,规则自定
一、游戏场景设计
当设计射箭游戏的游戏场景时,我们需要选择森林为主题,通过添加自然元素如各种不同的树木与植被,以及地形特征如高峰、低谷,可以让场景变得更加生动。此外,考虑到游戏的互动性,我们还可以在场景中添加一些不同的固定靶和移动靶。
二、游戏人物设计
当设计射箭游戏的游戏人物时,人物视角和人物移动是至关重要的两个方面,它们直接影响着玩家的游戏体验和操作感觉。
人物视角:
人物视角是玩家在游戏中所看到的角度和画面,我们使用第一人称,帮助玩家更准确地瞄准目标并进行射击。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLook : MonoBehaviour
{
// Start is called before the first frame update
public float mouseSensitivity = 300f;
public Transform playerBody;
float xRotation = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);// limit the angle
// rotate the camera within Y axis
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
// rotate the player within X axis
playerBody.Rotate(Vector3.up * mouseX);
}
}
人物移动:
人物移动是指游戏人物在游戏世界中的移动方式和动作表现。我们使用最简单直观的控制方式,由键盘直接控制。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Scripting.APIUpdating;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
private float gravity = 9.8f;
// Start is called before the first frame update
Vector3 move;
void Start()
{
}
void Update()
{
if(controller.isGrounded){
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
move = transform.right * x + transform.forward * z;
}
move.y = move.y - gravity*Time.deltaTime;
controller.Move(move * speed * Time.deltaTime);
}
}
三、游戏武器设计
游戏的武器主要包括对弓的控制和箭的属性。我们为弓设计蓄力和相关的动画,然后根据蓄力时间给予箭不同的初始速度;箭会在击中目标或一段时间后消失,击中目标可以得分。箭的发射用鼠标控制。
箭的初始位置由人物所在位置决定,速度由蓄力时间决定,并在出手一定时间后消失。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ArrowFeature : MonoBehaviour
{
public Vector3 startPos;
public Vector3 startDir;
public Transform target;//collider transform
public float speed;
public float destoryTime;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
destoryTime = 10f;
}
void Update()
{
destoryTime -= Time.deltaTime;
if (destoryTime < 0)
{
Destroy(this.transform.gameObject);
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "target")
{
if (!rb.isKinematic)
{
rb.isKinematic = true;
target = collision.gameObject.transform;
transform.SetParent(target);
}
destoryTime = 5f;
}
}
}
四、游戏目标靶设计
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetController : MonoBehaviour
{
public int basepoint;//初始分数
public float aniSpeed = 1f;
public int scores;//单个靶点的分数
void Start()
{
this.tag = "target";
//初始分数
scores= 0;
}
void Update()
{
}
//打到靶子
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Arrow")
{
scores += 1;
//增加游戏总分数
Singleton<UserGUI>.Instance.AddScore(1);
}
}
}
五、天空盒
最后增加可以切换的天空盒。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SkyboxSwitcher : MonoBehaviour
{
public Material[] skyboxMaterials;
private int currentSkyboxIndex = 0;
void Start()
{
RenderSettings.skybox = skyboxMaterials[currentSkyboxIndex]; // 初始设置天空盒
}
void Update()
{
if (Input.GetKeyDown(KeyCode.P))
{
// 切换到下一个天空盒
SwitchSkybox();
}
}
void SwitchSkybox()
{
currentSkyboxIndex = (currentSkyboxIndex + 1) % skyboxMaterials.Length
RenderSettings.skybox = skyboxMaterials[currentSkyboxIndex];
}
}
视频演示
射箭