unity制作幽灵猎手射击游戏

2023-11-23 02:41

本文主要是介绍unity制作幽灵猎手射击游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 介绍
  • 人物向着鼠标点击的位置跑动、旋转
  • lerp函数让摄像机平滑跟随
  • 敌人导航
  • 敌人攻击
  • 发射子弹攻击敌人
  • 玩家健康
  • 敌人健康
  • 分数显示
  • 刷怪笼
  • 游戏结束动画


介绍

在这里插入图片描述

在这里插入图片描述

玩家鼠标控制人物转向
玩家鼠标点击控制光线发射的终点
玩家受到伤害屏幕闪红
有三个怪物生成点
玩家射杀敌人获得分数

关键技术:动画器、屏幕射线检测负责转向、枪口粒子特效、枪口灯光、屏幕射线检测负责发射光线、line renderer、lerp函数相机移动、颜色lerp渐变


人物向着鼠标点击的位置跑动、旋转

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class PlayerMovement : MonoBehaviour
{public float speed = 6f;            // 玩家移动速度private Vector3 movement;           // 玩家的移动方向private Animator playerAC;          // 玩家的动画控制器private Rigidbody playerRigidbody; // 玩家的刚体组件LayerMask floorMask;// 初始化void Start(){// 获取动画控制器和刚体组件playerAC = GetComponent<Animator>();playerRigidbody = GetComponent<Rigidbody>();floorMask = LayerMask.GetMask("floor");}// 固定时问见新void FixedUpdate(){float h = Input.GetAxisRaw("Horizontal");float v = Input.GetAxisRaw("Vertical");// 移动 横向 和纵向Move(h, v);// 检测是否在移动,播放相应动画Animating(h, v);turning();}// 检测是否在移动,播放相应动画void Animating(float h, float v){// 只有h不等于0或者v不等于0才应该是移动bool walking = h != 0f || v != 0f;playerAC.SetBool("iswalking", walking);}// 移动void Move(float h, float v){// 设置移动的方向向量movement.Set(h, 0f, v);movement = movement.normalized * speed * Time.deltaTime;// 使用Rigidbody组件移动玩家playerRigidbody.MovePosition(transform.position + movement);}void turning(){Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit cameraHit;if (Physics.Raycast(cameraRay, out cameraHit, 100f, floorMask)){Vector3 playerToMouse = cameraHit.point - transform.position;playerToMouse.y = 0f;Quaternion newQuaternion = Quaternion.LookRotation(playerToMouse);playerRigidbody.MoveRotation(newQuaternion);}}}

void Start()

此函数在脚本开始运行时被调用。
它获取了动画控制器(playerAC)和刚体组件(playerRigidbody)。
设置了地面层的遮罩(floorMask)。
void FixedUpdate()

此函数在固定的时间间隔内被调用,用于物理相关的更新。
获取水平轴(h)和垂直轴(v)的输入值。
调用Move(h, v)函数进行移动。
调用Animating(h, v)函数根据移动状态播放相应的动画。
调用turning()函数根据鼠标位置旋转玩家角色。
void Animating(float h, float v)

检测是否在移动,并根据移动状态设置动画参数。
当h或v不等于0时,设置iswalking布尔参数为true,表示正在移动。
void Move(float h, float v)

设置移动方向向量movement。
使用标准化后的移动方向向量乘以速度和时间间隔,得到移动的位移向量。
使用刚体组件(playerRigidbody)将玩家位置进行移动。
void turning()

创建一条从主摄像机通过鼠标位置的射线(cameraRay)。
使用射线与地面层遮罩(floorMask)进行碰撞检测,并获取碰撞结果(cameraHit)。
计算玩家角色指向鼠标位置的向量(playerToMouse)。
将向量的y分量设为0,以保持在水平平面上旋转。
创建一个新的四元数(newQuaternion),表示玩家角色旋转的目标方向。
使用刚体组件(playerRigidbody)将玩家角色的旋转进行平滑插值。

在这里插入图片描述


lerp函数让摄像机平滑跟随

using UnityEngine;
using System.Collections;public class CameraFollow : MonoBehaviour {public Transform target;public float smoothing = 5f;Vector3 offset;// Use this for initializationvoid Start () {offset = transform.position - target.position;}// Update is called once per framevoid Update () {Vector3 pos = target.position + offset;transform.position = Vector3.Lerp(transform.position, pos, smoothing * Time.deltaTime);}
}

它通过Lerp方法将相机的位置平滑地移动到目标物体的位置。
首先,计算新的相机位置pos,该位置是目标物体的位置加上初始偏移量offset。
然后,使用Vector3.Lerp方法将相机当前的位置(transform.position)与新位置pos之间进行线性插值,以实现平滑过渡。
插值的速度由smoothing变量和Time.deltaTime控制。


敌人导航

using UnityEngine;
using UnityEngine.AI;
using System.Collections;public class EnemyMovement : MonoBehaviour {Transform player; // 目标位置:英雄NavMeshAgent nav; // 导航代理EnemyHealth enemyHealth;Playerhealth playerHealth;// Use this for initializationvoid Start () {player = GameObject.FindGameObjectWithTag("Player").transform;nav = GetComponent<NavMeshAgent>();enemyHealth=GetComponent<EnemyHealth>();playerHealth=player.GetComponent<Playerhealth>();}// Update is called once per framevoid Update () {if(enemyHealth.currentHealth > 0 && playerHealth.currentHealth > 0)nav.SetDestination(player.position);else{nav.enabled=false;}
}
}

Start()函数:初始化敌人角色的位置和导航代理,并获取敌人和英雄角色的健康组件。
Update()函数:如果敌人和英雄角色的健康状态都大于0,使用导航代理将敌人角色移动到英雄角色的位置;否则,禁用导航代理停止敌人角色的移动。


敌人攻击

using System.Collections;
using UnityEngine.UI;
using UnityEngine;public class EnemyAttack : MonoBehaviour {Playerhealth playerHealth;GameObject player;public int attack=10;public float attackBetweenTime=0.5f;float timer;public AudioSource playerAudio;bool inRange;void Start () {playerAudio = GetComponent<AudioSource>();player = GameObject.FindGameObjectWithTag("Player");playerHealth = player.GetComponent<Playerhealth>();}void Update () {// 如果收到伤害,显示受伤闪烁效果timer+=Time.deltaTime;// 如果在攻击范围内,执行攻击逻辑if (timer > attackBetweenTime&&inRange){Attack();}}void OnTriggerEnter(Collider other) {// 如果检测到玩家进入攻击范围,设置 inRange 标志为 trueif (other.gameObject == player) {inRange = true;}}void OnTriggerExit(Collider other) {// 如果检测到玩家离开攻击范围,设置 inRange 标志为 falsif (other.gameObject == player) {inRange = false;}}void Attack() {timer=0;if (playerHealth.currentHealth > 0) {playerHealth.OnAttack(attack);}}void Die() {// 在此添加死亡的相关逻辑,例如播放死亡动画、停止移动等}
}

Start()函数:获取玩家的健康组件和游戏对象,并初始化音频源。
Update()函数:检测计时器,并在攻击范围内执行攻击逻辑。
OnTriggerEnter(Collider other)函数:当检测到玩家进入攻击范围时,设置inRange标志为true。
OnTriggerExit(Collider other)函数:当检测到玩家离开攻击范围时,设置inRange标志为false。
Attack()函数:执行攻击逻辑,重置计时器,并检查玩家是否存活,然后对玩家进行攻击。


发射子弹攻击敌人

using UnityEngine;
using System.Collections;public class PlayerShooting : MonoBehaviour
{AudioSource gunAudio;Light gunLight;LineRenderer  gunLine;Ray gunRay;RaycastHit gunHit;public LayerMask layerMask;ParticleSystem gunParticies;float timer;public int atk=20;void Start(){gunAudio = GetComponent<AudioSource>();gunLight = GetComponent<Light>();gunLine = GetComponent<LineRenderer>();//	layerMask = LayerMask.GetMask("shoot");gunParticies=GetComponent<ParticleSystem>();}void Update(){timer+=Time.deltaTime;if (Input.GetButtonDown("Fire1")){shoot();}if (timer>0.1f){timer=0;gunLine.enabled=false;gunLight.enabled=false;}}void shoot() {//鼓gunAudio.Play();//光源gunLight.enabled = true;//枪gunLine.enabled = true;gunRay.origin = transform.position;//gunRay.direction = transform.forward;gunRay.direction = transform.TransformDirection(Vector3.forward);//检的第一个点gunLine.SetPosition(0, transform.position);gunParticies.Stop();gunParticies.Play();//判断是否击中敌人if (Physics.Raycast(gunRay, out gunHit, 100f, layerMask)) {EnemyHealth enemyHealth = gunHit.collider.GetComponent<EnemyHealth>();if (enemyHealth != null){Debug.Log("打到Zombunny");// 在这里处理击中敌人的逻辑enemyHealth.OnAttack(atk);}gunLine.SetPosition(1, gunHit.point);//在这里处理击中敌人的逻辑}else {gunLine.SetPosition(1, transform.position + gunRay.direction* 100f);}}}

Start()函数:初始化枪声音频源、枪光源、射线渲染器和粒子系统。

Update()函数:更新计时器,并在按下"Fire1"键时触发射击逻辑。

shoot()函数:处理射击逻辑,播放枪声音效、启用枪光源和射线渲染器,发射射线进行击中检测。如果击中敌人,则处理敌人受伤逻辑,并在射线上显示击中点。如果没有击中敌人,则在射线上显示射程范围内的终点。

在这里插入图片描述


玩家健康

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Playerhealth : MonoBehaviour
{public int startingHealth = 100;public int currentHealth;public Slider slider;public Image hurtImage;bool isDamage;private AudioSource playerAudio;public AudioClip deadclip;public Color flashColor = new Color(1f, 0f, 0f, 1f);public Color clearColor = Color.clear;Animator anim;PlayerMovement playermove;// Use this for initializationvoid Start(){playerAudio = GetComponent<AudioSource>();currentHealth = startingHealth;anim=GetComponent<Animator>();playermove=GetComponent<PlayerMovement>();}// Update is called once per framevoid Update(){if (isDamage)hurtImage.color = flashColor;else{hurtImage.color = Color.Lerp(hurtImage.color,clearColor,Time.deltaTime*5);}isDamage = false;// 检查当前生命值是否小于等于 0}// 受伤方法public void OnAttack(int damage){isDamage=true;// 减少生命值currentHealth -= damage;// 更新滑动条的值slider.value = currentHealth;// 播放受伤音效playerAudio.Play();if (currentHealth <= 0){// 如果生命值小于等于 0,则触发死亡事件Die();}}// 死亡方法void Die(){playerAudio.clip=deadclip;playerAudio.Play();anim.SetTrigger("die");playermove.enabled=false;}}

Start()函数:初始化玩家的血量、音频源、动画组件和移动组件。

Update()函数:更新受伤图像的颜色,将其逐渐恢复到透明,重置受伤标志。

OnAttack(int damage)函数:处理玩家受到攻击时的逻辑,减少生命值、更新滑动条的值、播放受伤音效,并在生命值小于等于0时触发死亡逻辑。

Die()函数:处理玩家死亡时的逻辑,播放死亡音效,触发死亡动画,禁用移动组件。

在这里插入图片描述


敌人健康

using UnityEngine;
using UnityEngine.AI;
using System.Collections;public class EnemyHealth : MonoBehaviour
{// 初始血量public int startingHealth = 50;// 当前血量public int currentHealth;// 敌人音频源AudioSource enemyAudioSource;public AudioClip enermyclip;bool isdie;Animator	 anim;// 初始化void Start(){currentHealth = startingHealth;enemyAudioSource = GetComponent<AudioSource>();anim=GetComponent<Animator>();}// 更新方法,每帧调用一次void Update(){}// 受伤方法public void OnAttack(int damage){// 减少血量currentHealth -= damage;// 播放音效enemyAudioSource.Play();if (currentHealth<0&&!isdie){Dead();}}void Dead(){isdie =true;anim.SetTrigger("dead");gameObject.GetComponent<NavMeshAgent>().enabled = false;gameObject.GetComponent<EnemyMovement>().enabled = false;enemyAudioSource.clip=enermyclip;enemyAudioSource.Play();Destroy(this.gameObject,1.1f);	ScoreManager.score+=10;}
}

Start()函数:初始化敌人的血量、音频源和动画组件。

OnAttack(int damage)函数:处理敌人受到攻击时的逻辑,减少血量、播放音效,并在血量为零时执行死亡逻辑。

Dead()函数:处理敌人死亡时的逻辑,触发死亡动画、禁用导航代理和敌人移动组件,播放死亡音效,延迟一定时间后销毁敌人游戏对象,增加得分。


分数显示

using UnityEngine;
using System.Collections;
using UnityEngine.UI;public class ScoreManager : MonoBehaviour
{public static int score;Text text;void Start(){text = GetComponent<Text>();}void Update(){text.text = "SCORE: " + score;}
}

刷怪笼

using UnityEngine;
using System.Collections;public class GameOverManager : MonoBehaviour {public Playerhealth playerHealth;Animator anim;public GameObject PLAYER;// Use this for initializationvoid Start () {anim = GetComponent<Animator>();playerHealth=PLAYER.GetComponent<Playerhealth>();}// Update is called once per framevoid Update () {if(playerHealth.currentHealth <= 0) {anim.SetTrigger("GameOver");}}
}

给物体添加多个脚本,放入不同的预制体。

在这里插入图片描述
在这里插入图片描述


游戏结束动画

在这里插入图片描述
在这里插入图片描述






这篇关于unity制作幽灵猎手射击游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/414777

相关文章

使用Python制作一个PDF批量加密工具

《使用Python制作一个PDF批量加密工具》PDF批量加密‌是一种保护PDF文件安全性的方法,通过为多个PDF文件设置相同的密码,防止未经授权的用户访问这些文件,下面我们来看看如何使用Python制... 目录1.简介2.运行效果3.相关源码1.简介一个python写的PDF批量加密工具。PDF批量加密

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

第四次北漂----挣个独立游戏的素材钱

第四次北漂,在智联招聘上,有个小公司主动和我联系。面试了下,决定入职了,osg/osgearth的。月薪两万一。 大跌眼镜的是,我入职后,第一天的工作内容就是接手他的工作,三天后他就离职了。 我之所以考虑入职,是因为 1,该公司有恒歌科技的freex平台源码,可以学学,对以前不懂的解解惑。 2,挣点素材钱,看看张亮002的视频,他用了6000多,在虚幻商城买的吸血鬼游戏相关的素材,可以玩两年。我

OpenStack离线Train版安装系列—0制作yum源

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系