基于Unity开发实现的坦克游戏设计

一、介绍

该项目以虚拟现实技术课程中老师所教授 UnityChan 相关 人物角色动画控制为基础,引入室外场景模型并添加光照和阴影;添加交互性元素如 发射炮弹,键盘按钮移动坦克;实现第一、三人称视角切换。

开发平台为 Unity 2018.4.21f1(64-bit),操作系统为 Windows 10(64 位)。

二、操作说明

使用 Visual Studio 编译这个游戏,然后运行。

2.1 这个是游戏刚开始进入时的场景

2.2 移动人物漫游场景

WSAD 键用来控制坦克的位置,行走用户以第三人称视角在整个场景中进行移动。

2.3 移动鼠标切换视角

可以移动鼠标,来切换视角

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CHzGIqX2-1653294122999)
(https://www.writebug.com/myres/static/uploads/2022/5/21/44912dd0f2bce5f0058dcf67ebe48014.writebug)]

2.4 鼠标点击发射炮弹

点击鼠标的时候,可以发射炮弹到一个位置,观看到炸弹爆炸的效果

扫描二维码关注公众号,回复: 14170160 查看本文章

三、探索的技术

3.1 多摄像机切换

using UnityEngine;
public class CameraControl : MonoBehaviour
{
    public float m_DampTime = 0.2f;
    public float m_ScreenEdgeBuffer = 4f;
    public float m_MinSize = 6.5f;
    [HideInInspector] public Transform[] m_Targets;
    private Camera m_Camera;
    private float m_ZoomSpeed;
    private Vector3 m_MoveVelocity;
    private Vector3 m_DesiredPosition;
    private void Awake()
    {
        m_Camera = GetComponentInChildren<Camera>();
    }
    private void FixedUpdate()
    {
        Move();
        Zoom();
    }
    private void Move()
    {
        FindAveragePosition();
        transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);
    }
    private void FindAveragePosition()
    {
        Vector3 averagePos = new Vector3();
        int numTargets = 0;
        for (int i = 0; i < m_Targets.Length; i++)
        {
            if (!m_Targets[i].gameObject.activeSelf)
                continue;
            averagePos += m_Targets[i].position;
            numTargets++;
        }
        if (numTargets > 0)
            averagePos /= numTargets;
        averagePos.y = transform.position.y;
        m_DesiredPosition = averagePos;
    }
    private void Zoom()
    {
        float requiredSize = FindRequiredSize();
        m_Camera.orthographicSize = Mathf.SmoothDamp(m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
    }
    private float FindRequiredSize()
    {
        Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition);
        float size = 0f;
        for (int i = 0; i < m_Targets.Length; i++)
        {
            if (!m_Targets[i].gameObject.activeSelf)
                continue;
            Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position);
            Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos;
            size = Mathf.Max (size, Mathf.Abs (desiredPosToTarget.y));
            size = Mathf.Max (size, Mathf.Abs (desiredPosToTarget.x) / m_Camera.aspect);
        }
        size += m_ScreenEdgeBuffer;
        size = Mathf.Max(size, m_MinSize);
        return size;
    }
    public void SetStartPositionAndSize()
    {
        FindAveragePosition();
        transform.position = m_DesiredPosition;
        m_Camera.orthographicSize = FindRequiredSize();
    }
}

坦克生命值切换

using UnityEngine;
using UnityEngine.UI;
public class TankHealth : MonoBehaviour
{
    public float m_StartingHealth = 100f;
    public Slider m_Slider;
    public Image m_FillImage;
    public Color m_FullHealthColor = Color.green;
    public Color m_ZeroHealthColor = Color.red;
    public GameObject m_ExplosionPrefab;
    private AudioSource m_ExplosionAudio;
    private ParticleSystem m_ExplosionParticles;
    private float m_CurrentHealth;
    private bool m_Dead;
    private void Awake()
    {
        m_ExplosionParticles = Instantiate(m_ExplosionPrefab).GetComponent<ParticleSystem>();
        m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource>();
        m_ExplosionParticles.gameObject.SetActive(false);
    }
    private void OnEnable()
    {
        m_CurrentHealth = m_StartingHealth;
        m_Dead = false;
        SetHealthUI();
    }
    public void TakeDamage(float amount)
    {
        m_CurrentHealth -= amount;
        SetHealthUI();
        if (m_CurrentHealth <= 0f && !m_Dead)
        {
            OnDeath();
        }
    }
    private void SetHealthUI()
    {
        m_Slider.value = m_CurrentHealth;
        m_FillImage.color = Color.Lerp(m_ZeroHealthColor, m_FullHealthColor, m_CurrentHealth / m_StartingHealth);
    }
    private void OnDeath()
    {
        m_Dead = true;
        m_ExplosionParticles.transform.position = transform.position;
        m_ExplosionParticles.gameObject.SetActive(true);
        m_ExplosionParticles.Play();
        m_ExplosionAudio.Play();
        gameObject.SetActive(false);
    }

plosionParticles.gameObject.SetActive(true);
m_ExplosionParticles.Play();
m_ExplosionAudio.Play();
gameObject.SetActive(false);
}


猜你喜欢

转载自blog.csdn.net/newlw/article/details/124929546
今日推荐