Unity:是否有办法在跳跃,攻击或执行其他动作时停止某些脚本?



我是unity的初学者因此,我在这里有一个3脚本:

射击/进攻脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shoot : MonoBehaviour
{
private Animator anim;
public float cooldownTime = 2f;
private float nextFireTime = 0f;
public static int noOfClicks = 0;
float lastClickedTime = 0;
float maxComboDelay = 1;
private void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (anim.GetCurrentAnimatorStateInfo(0).normalizedTime > 0.7f && anim.GetCurrentAnimatorStateInfo(0).IsName("hit1"))
{
anim.SetBool("hit1", false);
noOfClicks = 0;
}

if (Time.time - lastClickedTime > maxComboDelay)
{
noOfClicks = 0;
}
//cooldown time
if (Time.time > nextFireTime)
{
// Check for mouse input
if (Input.GetMouseButtonDown(0))
{
OnClick();
}
}
}
void OnClick()
{
lastClickedTime = Time.time;
noOfClicks++;
if (noOfClicks == 1)
{
anim.SetBool("hit1", true);
}
noOfClicks = Mathf.Clamp(noOfClicks, 0, 3);
if (noOfClicks >= 2 && anim.GetCurrentAnimatorStateInfo(0).normalizedTime > 0.7f && anim.GetCurrentAnimatorStateInfo(0).IsName("hit1"))
{
anim.SetBool("hit1", false);
}
}
}

and about the bullet:

using UnityEngine;
using TMPro;
public class ProjectileGunTutorial : MonoBehaviour
{
//bullet 
public GameObject bullet;
//bullet force
public float shootForce, upwardForce;
//Gun stats
public float timeBetweenShooting, spread, reloadTime, timeBetweenShots;
public int magazineSize, bulletsPerTap;
public bool allowButtonHold;
int bulletsLeft, bulletsShot;
//Recoil
public Rigidbody playerRb;
public float recoilForce;
//bools
bool shooting, readyToShoot, reloading;
//Reference
public Camera fpsCam;
public Transform attackPoint;
//Graphics
public GameObject muzzleFlash;
public TextMeshProUGUI ammunitionDisplay;
//bug fixing :D
public bool allowInvoke = true;
private void Awake()
{
//make sure magazine is full
bulletsLeft = magazineSize;
readyToShoot = true;
}
private void Update()
{
MyInput();
//Set ammo display, if it exists :D
if (ammunitionDisplay != null)
ammunitionDisplay.SetText(bulletsLeft / bulletsPerTap + " / " + magazineSize / bulletsPerTap);
}
private void MyInput()
{
//Check if allowed to hold down button and take corresponding input
if (allowButtonHold) shooting = Input.GetKey(KeyCode.Mouse0);
else shooting = Input.GetKeyDown(KeyCode.Mouse0);
//Reloading 
if (Input.GetKeyDown(KeyCode.R) && bulletsLeft < magazineSize && !reloading) Reload();
//Reload automatically when trying to shoot without ammo
if (readyToShoot && shooting && !reloading && bulletsLeft <= 0) Reload();
//Shooting
if (readyToShoot && shooting && !reloading && bulletsLeft > 0)
{
//Set bullets shot to 0
bulletsShot = 0;
Shoot();
}
}
private void Shoot()
{
readyToShoot = false;
//Find the exact hit position using a raycast
Ray ray = fpsCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); //Just a ray through the middle of your current view
RaycastHit hit;
//check if ray hits something
Vector3 targetPoint;
if (Physics.Raycast(ray, out hit))
targetPoint = hit.point;
else
targetPoint = ray.GetPoint(75); //Just a point far away from the player
//Calculate direction from attackPoint to targetPoint
Vector3 directionWithoutSpread = targetPoint - attackPoint.position;
//Calculate spread
float x = Random.Range(-spread, spread);
float y = Random.Range(-spread, spread);
//Calculate new direction with spread
Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, 0); //Just add spread to last direction
//Instantiate bullet/projectile
GameObject currentBullet = Instantiate(bullet, attackPoint.position, Quaternion.identity); //store instantiated bullet in currentBullet
//Rotate bullet to shoot direction
currentBullet.transform.forward = directionWithSpread.normalized;
//Add forces to bullet
currentBullet.GetComponent<Rigidbody>().AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
currentBullet.GetComponent<Rigidbody>().AddForce(fpsCam.transform.up * upwardForce, ForceMode.Impulse);
//Instantiate muzzle flash, if you have one
if (muzzleFlash != null)
Instantiate(muzzleFlash, attackPoint.position, Quaternion.identity);
bulletsLeft--;
bulletsShot++;
//Invoke resetShot function (if not already invoked), with your timeBetweenShooting
if (allowInvoke)
{
Invoke("ResetShot", timeBetweenShooting);
allowInvoke = false;
//Add recoil to player (should only be called once)
playerRb.AddForce(-directionWithSpread.normalized * recoilForce, ForceMode.Impulse);
}
//if more than one bulletsPerTap make sure to repeat shoot function
if (bulletsShot < bulletsPerTap && bulletsLeft > 0)
Invoke("Shoot", timeBetweenShots);
}
private void ResetShot()
{
//Allow shooting and invoking again
readyToShoot = true;
allowInvoke = true;
}
private void Reload()
{
reloading = true;
Invoke("ReloadFinished", reloadTime); //Invoke ReloadFinished function with your reloadTime as delay
}
private void ReloadFinished()
{
//Fill magazine
bulletsLeft = magazineSize;
reloading = false;
}
}

和最后一个是球员移动脚本:

using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed;
public float rotationSpeed;
public float jumpHeight;
[SerializeField]
private float gravityMultiplier;
[SerializeField]
private Transform cameraTransform;
private Animator animator;
private CharacterController characterController;
private float ySpeed;
private float originalStepOffset;
private bool isJumping;
private bool isGrounded;
void Start()
{
animator = GetComponent<Animator>();
characterController = GetComponent<CharacterController>();
originalStepOffset = characterController.stepOffset;
}
void Update()
{
if(animator.GetCurrentAnimatorStateInfo(0).IsName("hit1"))
{
return;
}
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 movementDirection = new Vector3(horizontalInput, 0, verticalInput);
float magnitude = Mathf.Clamp01(movementDirection.magnitude) * speed;
movementDirection = Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * movementDirection;
movementDirection.Normalize();
float gravity = Physics.gravity.y * gravityMultiplier;
ySpeed += gravity * Time.deltaTime;
if (characterController.isGrounded)
{
characterController.stepOffset = originalStepOffset;
ySpeed = -0.5f;
animator.SetBool("IsGrounded", true);
isGrounded = true;
animator.SetBool("IsJumping", false);
isJumping = false;
animator.SetBool("IsFalling", false);
if (Input.GetButtonDown("Jump"))
{
ySpeed = Mathf.Sqrt(jumpHeight * -3 * gravity);
animator.SetBool("IsJumping", true);
isJumping = true;            }
}    
else
{
characterController.stepOffset = 0;
animator.SetBool("IsGrounded", false);
isGrounded = false;
if ((isJumping && ySpeed < 0) || ySpeed < -2)
{
animator.SetBool("IsFalling", true);
}
}
Vector3 velocity = movementDirection * magnitude;
velocity = AdjustVelocityToSlope(velocity);
velocity.y += ySpeed;
characterController.Move(velocity * Time.deltaTime);
if (movementDirection != Vector3.zero)
{
animator.SetBool("IsMoving", true);
Quaternion toRotation = Quaternion.LookRotation(movementDirection, Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime);
}
else
{
animator.SetBool("IsMoving", false);
}
}
private Vector3 AdjustVelocityToSlope(Vector3 velocity)
{
var ray = new Ray(transform.position, Vector3.down);
if (Physics.Raycast(ray, out RaycastHit hitInfo, 0.2f))
{var slopeRotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
var adjustedVelocity = slopeRotation * velocity;
if (adjustedVelocity.y < 0)
{
return adjustedVelocity;
}
}
return velocity;
}
}

我的角色已经能够跳跃,奔跑,射击和空闲,但当我在跳跃时点击射击按钮时,子弹会在跳跃动画中出现。这是非常奇怪和不必要的,所以有没有一种方法可以延迟子弹并在它落地时射击?

与其延迟拍摄,我建议只是在跳跃时阻止它。在PlayerMovement脚本中有isJumping字段。您可以为它创建一个公共属性,并在拍摄前检查它,使用SerializedField引用移动脚本。如果你检测到点击,你首先检查我们是否在跳跃。如果是,就返回,什么都不做。

有一个实现可能会有所帮助:时间。timeScale = .1f;//播放速度比正常速度慢10倍;

float timeScaleDelta = .05f;
// Use this for initialization
void Start () {
...
}
// Update is called once per frame
void Update () {
...
float spX = Input.GetAxis("Horizontal");
float spY = Input.GetAxis("Vertical");
// spX, spY Handling up and down
if (Input.GetKeyDown(KeyCode.W)) // When W is pressed, the bullet time is accelerated
{
Time.timeScale += timeScaleDelta;
}
else if (Input.GetKeyDown(KeyCode.S)) // When pressing S, slow down the bullet time to play
{
if (Time.timeScale < 0) Time.timeScale = 0;
else Time.timeScale -= timeScaleDelta;
}
}

如果你控制主角跳跃和飞行。按几次S键,可以看到动作变慢了,可以清楚地看到慢动作。

最新更新