How to stop an audioclip when the condition is over? - c#

I'm making a game in Unity and I'm having some problems on adding audio in my enemies. I have an audio clip for walking, attacking and dying. But when I play the game the audioclips starts playing in the right condition, but they never stop like I was expecting. I want them to only play while they're in the right condition and stop playing when in another condition.
Here's my code:
public override void ActionCharacter(){
if (!isDead) {
currentTimeToChangeAction += Time.deltaTime;
if (currentDistanceToPlayer <= distanceToAttack && currentTimeToAttack < timeToAttack) {
currentTimeToAttack += Time.deltaTime;
inAttack = true;
axiVertical = 0;
audio.PlayOneShot(ZombieWalkAudio);
animationCharacter.CrossFade (attackAnimation.name);
} else {
currentTimeToAttack = 0;
inAttack = false;
}
if (inStun) {
currentTimeToStun += Time.deltaTime;
if (currentTimeToStun > timeToStun) {
currentTimeToStun = 0;
inStun = false;
}
axiVertical = 0;
animationCharacter.CrossFade (damageAnimation.name);
}
if (!inAttack && !inStun) {
if (currentTimeToChangeAction > timeToChangeAction) {
currentTimeToChangeAction = 0;
//axiHorizontal = Time.deltaTime * walkVelocity;
axiVertical = Time.deltaTime * walkVelocity;
audio.PlayOneShot(ZombieAttackAudio);
}
if (currentDistanceToPlayer <= distanceMinToRun) {
callRun = true;
} else {
callRun = false;
}
transform.LookAt (player.transform);
//currentGun.Shoot();
}
}
}

Related

Encountering a " does not contain a definition for " error with a script. What may be causing this in my code?

I was able to troubleshoot the issues up until a certain point when I came across this error in unity:
Assets\code\StalkerAI.cs(164,45): error CS0117: 'NavMeshAgent' does not contain a definition for 'setDestination'
I know for certain that this should have worked for this function, but I am unsure why it is not. I would like to know what exactly I am getting wrong here.
Here is the issue code that they are seeing (I would be more specific if I knew which "NavMeshAgent.setDestination" they are speaking of, but here we are):
m_WaitTime = startWaitTime;
m_TimeToRotate = timeToRotate;
m_CurrentWaypointIndex = 0;
NavMeshAgent = GetComponent<NavMeshAgent>();
NavMeshAgent.isStopped = false;
NavMeshAgent.speed = speedWalk;
NavMeshAgent.SetDestination(waypoints[m_CurrentWaypointIndex].position);
}
void Update()
{
EnviromentView();
if (!m_IsPatrol)
{
Chasing();
}
else
{
Patroling();
}
}
private void Chasing()
{
m_PlayerNear = false;
playerLastPosition = Vector3.zero;
if (!m_CaughtPlayer)
{
Move(speedRun);
NavMeshAgent.SetDestination(m_PlayerPosition);
}
if(NavMeshAgent.remainingDistance <= NavMeshAgent.stoppingDistance){
if(m_WaitTime <= 0 && !m_CaughtPlayer && Vector3.Distance(transform.position, GameObject.FindGameObjectWithTag("player").transform.position)>= 6f)
{
m_IsPatrol = true;
m_PlayerNear = false;
Move(speedWalk);
m_TimeToRotate = timeToRotate;
m_WaitTime = startWaitTime;
NavMeshAgent.SetDestination(waypoints[m_CurrentWaypointIndex].position);
}
else
{
if(Vector3.Distance(transform.position, GameObject.FindGameObjectWithTag("player").transform.position)>= 2.5f)
{
Stop();
m_WaitTime -= Time.deltaTime;
}
}
}
}
private void Patroling()
{
if (m_PlayerNear)
{
if(m_TimeToRotate <= 0)
{
Move(speedWalk);
LookingPlayer(playerLastPosition);
}
else
{
Stop();
m_TimeToRotate -= Time.deltaTime;
}
}
else
{
m_PlayerNear = false;
playerLastPosition = Vector3.zero;
NavMeshAgent.SetDestination(waypoints[m_CurrentWaypointIndex].position);
if(NavMeshAgent.remainingDistance <= NavMeshAgent.stoppingDistance)
{
if(m_WaitTime <=0)
{
NextPoint();
Move(speedWalk);
m_WaitTime = startWaitTime;
}
else
{
Stop();
m_WaitTime -= Time.deltaTime;
}
}
}
}
void Move(float speed)
{
NavMeshAgent.isStopped = false;
NavMeshAgent.speed = speed;
}
void Stop()
{
NavMeshAgent.isStopped = true;
NavMeshAgent.speed = 0;
}
public void NextPoint()
{
m_CurrentWaypointIndex = (m_CurrentWaypointIndex + 1) % waypoints.Length;
NavMeshAgent.SetDestination(waypoints[m_CurrentWaypointIndex].position);
}
void CaughtPlayer()
{
m_CaughtPlayer = true;
}
void LookingPlayer(Vector3 player)
{
NavMeshAgent.SetDestination(player);
if(Vector3.Distance(transform.position, player)<= 0.3)
{
if(m_WaitTime <= 0)
{
m_PlayerNear = false;
Move(speedWalk);
UnityEngine.AI.NavMeshAgent.setDestination(waypoints[m_CurrentWaypointIndex].position);
If you want the full script, let me know.
Seems like you named your variable exactly like the class NavMeshAgent. I would recommend to slightly change the variable name - maybe this is causing some issues.
You could also try using the property NavMeshAgent.destination = (Vector3) newDestination.

I added coyote time to my jump in my 2d platformer(where you can jump shortly after jumping off the ledge), but it's not working

All the settings are there and the code seems correct to me, but it's just not working.
This is the code that involves coyote time:
[SerializeField, Range(0f, 0.3f)] private float _coyoteTime = 0.2f;
private float coyoteCounter
private void FixedUpdate()
{
onGround = ground.GetOnGround();
velocity = body.velocity;
if(onGround && body.velocity.y == 0)
{
jumpPhase = 0;
coyoteCounter = _coyoteTime;
isJumping = false;
}
else
{
coyoteCounter -= Time.deltaTime;
}
private void JumpAction()
{
if(coyoteCounter > 0f || jumpPhase < maxAirJumps && isJumping)
{
if(isJumping)
{
jumpPhase += 1;
}
jumpBufferCounter = 0;
coyoteCounter = 0;
jumpSpeed = Mathf.Sqrt(-2f * Physics2D.gravity.y * jumpHeight);
isJumping = true;
if(velocity.y > 0f)
{
jumpSpeed = Mathf.Max(jumpSpeed - velocity.y, 0f);
}
velocity.y += jumpSpeed;
}
}
If someone could please explain to me what is going wrong, that would be greatly appreciated. Thanks!
First you don't need to use fixed update for this, your ground.GetOnGround is probably filled on FixedUpdate itself. FixedUpdate is mostly useful when you are dealing with AddForce for a certain amount of time not just one frame.
Second if you are using FixedUpdate use fixedDeltaTime instead of deltaTime.
This is the barebone of the effect, you can add multi jump to the logic yourself.
// Will set from checking the ground contact on update
bool IsOnGround = true;
bool WasOnGround = true;
bool LedgeFall = false;
bool IsJumping = false;
bool ThereIsGroundContact()
{
// Check if character is contact with ground with raycast or overlaps
}
void OnUpdate()
{
IsOnGround = ThereIsGroundContact();
if (IsOnGround && !WasOnGround)
{
OnLand();
}
// if falling from ledge
if (!IsOnGround && WasOnGround && velocity.y <= 0)
{
LedgeFall = true;
CoyoteTimer = 0;
}
if (LedgeFall){
CoyoteTimer += Time.deltaTime;
}
if (LedgeFall && CoyoteTimer >= _CoyoteTime){
LedgeFall = false;
}
// You can process jump input here
if ((IsOnGround || LedgeFall) && JumpInputPressed)
IsJumping = true;
WasOnGround = IsOnGround;
}
void OnLand()
{
LedgeFall = false;
IsJumping = false;
CoyoteTimer = 0;
}
Hope this helps

Enemy AI not working properly with NavMesh

I been trying to create an AI for the enemy to patrol between some points and, when spot player in a certain range, the enemy stop the patrol and follows the player.
The thing is, if I only have the enemy to follow the player, works perfectly the same happens with just the patrol, but both together doesn't seem to work. The enemy acts in a weird way.
My code:
public void Start()
{
_navMeshAgent = this.GetComponent<NavMeshAgent>();
anim = GetComponent<Animator>();
if (_navMeshAgent == null)
{
Debug.LogError("not attached to " + gameObject.name);
}
else
{
if (_patrolPoints != null && _patrolPoints.Count >= 2)
{
_currentPatrolIndex = 0;
anim.SetBool("idle", true);
SetDestination();
}
else
{
Debug.Log("Insufficient patrol points.");
}
}
}
void Update()
{
if (player == null)
{
player = GameObject.Find("Player Character").GetComponent<Transform>();
}
if (Vector3.Distance(player.transform.position, this.transform.position) < 10)
{
chacePlayer();
}
else
{
patrol();
}
bool patrol()
{
Debug.Log("patrolling");
//Check if we're close to the destination.
if (_travelling && _navMeshAgent.remainingDistance <= 1.0f)
{
_travelling = false;
anim.SetBool("idle", false);
anim.SetBool("move", true);
//If we're going to wait, then wait dumbass!
if (_patrolWaiting)
{
_waiting = true;
_waitTimer = 0f;
anim.SetBool("idle", true);
anim.SetBool("move", false);
}
else
{
ChangePatrolPoint();
SetDestination();
}
}
//Instead if we're waiting...
if (_waiting)
{
_waitTimer += Time.deltaTime;
if (_waitTimer >= _totalWaitingTime)
{
_waiting = false;
anim.SetBool("move", true);
anim.SetBool("idle", false);
ChangePatrolPoint();
SetDestination();
}
}
return true;
}
}
private void SetDestination()
{
if (_patrolPoints != null)
{
Vector3 targetVector = _patrolPoints[_currentPatrolIndex].transform.position;
_navMeshAgent.SetDestination(targetVector);
_travelling = true;
////anim.SetBool("idle", false);
////anim.SetBool("move", true);
}
}
//Selects a new patrol point in the available list, but
//also with a small probability allows for us to move forward or backwards.
private void ChangePatrolPoint()
{
//Unity generate random number between 0 and 1
if (UnityEngine.Random.Range(0f, 1f) <= _switchProbability)
{
//decides if go forward or backwards: whatever the value, make the oposite
_patrolForward = !_patrolForward;
}
if (_patrolForward)
{
//if the patrolpoint exceedes patrolpoints.count, go backs to zero
_currentPatrolIndex = (_currentPatrolIndex + 1) % _patrolPoints.Count;
}
else
{
if (--_currentPatrolIndex < 0)
{
_currentPatrolIndex = _patrolPoints.Count - 1;
}
}
}
void chacePlayer()
{
Vector3 direction = player.transform.position - this.transform.position;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction), 0.1f);
direction.y = 0;
if (direction.magnitude > 2)
{
this.transform.Translate(0, 0, 0.05f);
Debug.Log("chacing");
}
}
At first I thought it was because the code was running both together so I put a Debug to see if it was that, but the debug of the patrol stops every time the enemy is following the player.
Can someone please help me?

Why does Unity crash when I move a sprite horizontally?

I just started Unity and I was making a 2D game of a player (sprite) that shoots an arrow when I click a specific button. The player moves vertically and the arrow moves horizontally. The player moves fine but, when I click to shoot the arrow, Unity crashes and I have to close it from Task Manager.
The code shows 0 errors and everything else works fine except for Unity.
I don't know where the problem is so, I'll show the whole code; the function that shoots the arrows is called shootingsysytem.
void Start()
{
health = 100;
playerspeed = 2;
shotspeed = 3;
bulletcount = 3;
playerpos();
if (delay <= 0)
{
delay = 0;
}
stopbullets();
}
// Update is called once per frame
void Update()
{
playermouvement();
shootingsystem();
playerpos();
delay -= Time.deltaTime;
}
public void playermouvement()// works
{
if (Input.GetKey("z"))
{
player[0].transform.Translate(Vector2.up * Time.deltaTime * playerspeed);
}
if (Input.GetKey("s"))
{
player[0].transform.Translate(Vector2.down * Time.deltaTime * playerspeed);
}
}// works
public void shootingsystem() // this function shoots the arrows.........
{
if (Input.GetKey("k"))
{
if (bulletcount == 3 & delay <= 0.0f)
{
bullet3shot = true;
while (bullet3shot)
{
player[3].transform.Translate(Vector2.left * Time.deltaTime * shotspeed);
}
if (delay <= 0.0f)
{
bulletcount--;
delay = 1;
}
}
else if (bulletcount == 2 & delay <= 0.0f)
{
bullet2shot = true;
while (bullet2shot)
{
player[2].transform.position += goingside * Time.deltaTime;
}
if (delay <= 0.0f)
{
bulletcount--;
delay = 1;
}
}
else if (bulletcount == 1 & delay <= 0.0f)
{
bullet1shot = true;
while (bullet1shot)
{
player[1].transform.Translate(Vector2.left * Time.deltaTime * shotspeed);
}
if (delay <= 0.0f)
{
bulletcount--;
bulletcount = 3; // remove later
delay = 1;
}
}
}
}
public void playerpos()//works
{
playerposition = player[0].transform.position;
if (!bullet1shot)
{
player[1].transform.position = playerposition;
}
if (!bullet2shot)
{
player[2].transform.position = playerposition;
}
if (!bullet3shot)
{
player[3].transform.position = playerposition;
}
}//works
private void stopbullets()
{
if (player[1].transform.position.x <= -13) //stop first bullet
{
bullet1shot = false;
}
if (player[2].transform.position.x <= -13) //stop second bullet
{
bullet2shot = false;
}
if (player[3].transform.position.x <= -13) //stop third bullet
{
bullet3shot = false;
}
}
Its because you have an infinite loop.
bullet1shot = true;
while (bullet1shot)
{
player[1].transform.Translate(Vector2.left * Time.deltaTime * shotspeed);
}

How to make a continuous rotation by changing this c# code

Im using Unity and have asked this on there forums however have not had any replies. Ive found this example from a plugin where I am trying to use the kinect to rotate an object using my right hand to rotate it right and the left to rotate left. I have managed to get the object to do this apart from it stops at each side of the object, but cant work out what part of the code is doing this.
Thanks
using UnityEngine;
using System.Collections;
using System;
public class GestureListener : MonoBehaviour, KinectGestures.GestureListenerInterface
{
// GUI Text to display the gesture messages.
public GUIText GestureInfo;
private bool raiselefthand;
private bool raiserighthand;
public bool IsSwipeLeft()
{
if(raiserighthand)
{
raiserighthand = false;
return true;
}
return false;
}
public bool IsSwipeRight()
{
if(raiselefthand)
{
raiselefthand = false;
return true;
}
return false;
}
public void UserDetected(uint userId, int userIndex)
{
// detect these user specific gestures
KinectManager manager = KinectManager.Instance;
manager.DetectGesture(userId, KinectGestures.Gestures.RaiseLeftHand);
manager.DetectGesture(userId, KinectGestures.Gestures.RaiseRightHand);
if(GestureInfo != null)
{
GestureInfo.GetComponent<GUIText>().text = "Swipe left or right to change the slides.";
}
}
public void UserLost(uint userId, int userIndex)
{
if(GestureInfo != null)
{
GestureInfo.GetComponent<GUIText>().text = string.Empty;
}
}
public void GestureInProgress(uint userId, int userIndex, KinectGestures.Gestures gesture,
float progress, KinectWrapper.NuiSkeletonPositionIndex joint, Vector3 screenPos)
{
// don't do anything here
}
public bool GestureCompleted (uint userId, int userIndex, KinectGestures.Gestures gesture,
KinectWrapper.NuiSkeletonPositionIndex joint, Vector3 screenPos)
{
string sGestureText = gesture + " detected";
if(GestureInfo != null)
{
GestureInfo.GetComponent<GUIText>().text = sGestureText;
}
if(gesture == KinectGestures.Gestures.RaiseRightHand)
raiserighthand = true;
else if(gesture == KinectGestures.Gestures.RaiseLeftHand)
raiselefthand = true;
return true;
}
public bool GestureCancelled (uint userId, int userIndex, KinectGestures.Gestures gesture,
KinectWrapper.NuiSkeletonPositionIndex joint)
{
// don't do anything here, just reset the gesture state
return true;
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PresentationScript : MonoBehaviour
{
public bool slideChangeWithGestures = true;
public bool slideChangeWithKeys = true;
public float spinSpeed = 5;
public bool autoChangeAlfterDelay = false;
public float slideChangeAfterDelay = 10;
public List<Texture> slideTextures;
public List<GameObject> horizontalSides;
// if the presentation cube is behind the user (true) or in front of the user (false)
public bool isBehindUser = false;
private int maxSides = 0;
private int maxTextures = 0;
private int side = 0;
private int tex = 0;
private bool isSpinning = false;
private float slideWaitUntil;
private Quaternion targetRotation;
private GestureListener gestureListener;
void Start()
{
// hide mouse cursor
Cursor.visible = false;
// calculate max slides and textures
maxSides = horizontalSides.Count;
maxTextures = slideTextures.Count;
// delay the first slide
slideWaitUntil = Time.realtimeSinceStartup + slideChangeAfterDelay;
targetRotation = transform.rotation;
isSpinning = false;
tex = 0;
side = 0;
if(horizontalSides[side] && horizontalSides[side].GetComponent<Renderer>())
{
horizontalSides[side].GetComponent<Renderer>().material.mainTexture = slideTextures[tex];
}
// get the gestures listener
gestureListener = Camera.main.GetComponent<GestureListener>();
}
void Update()
{
// dont run Update() if there is no user
KinectManager kinectManager = KinectManager.Instance;
if(autoChangeAlfterDelay && (!kinectManager || !kinectManager.IsInitialized() || !kinectManager.IsUserDetected()))
return;
if(!isSpinning)
{
if(slideChangeWithKeys)
{
if(Input.GetKeyDown(KeyCode.PageDown))
RotateToNext();
else if(Input.GetKeyDown(KeyCode.PageUp))
RotateToPrevious();
}
if(slideChangeWithGestures && gestureListener)
{
if(gestureListener.IsSwipeLeft())
RotateToNext();
else if(gestureListener.IsSwipeRight())
RotateToPrevious();
}
// check for automatic slide-change after a given delay time
if(autoChangeAlfterDelay && Time.realtimeSinceStartup >= slideWaitUntil)
{
RotateToNext();
}
}
else
{
// spin the presentation
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, spinSpeed * Time.deltaTime);
// check if transform reaches the target rotation. If yes - stop spinning
float deltaTargetX = Mathf.Abs(targetRotation.eulerAngles.x - transform.rotation.eulerAngles.x);
float deltaTargetY = Mathf.Abs(targetRotation.eulerAngles.y - transform.rotation.eulerAngles.y);
if(deltaTargetX < 1f && deltaTargetY < 1f)
{
// delay the slide
slideWaitUntil = Time.realtimeSinceStartup + slideChangeAfterDelay;
isSpinning = false;
}
}
}
private void RotateToNext()
{
// set the next texture slide
tex = (tex + 1) % maxTextures;
if(!isBehindUser)
{
side = (side + 1) % maxSides;
}
else
{
if(side <= 0)
side = maxSides - 1;
else
side -= 1;
}
if(horizontalSides[side] && horizontalSides[side].GetComponent<Renderer>())
{
horizontalSides[side].GetComponent<Renderer>().material.mainTexture = slideTextures[tex];
}
// rotate the presentation
float yawRotation = !isBehindUser ? 360f / maxSides : -360f / maxSides;
Vector3 rotateDegrees = new Vector3(0f, yawRotation, 0f);
targetRotation *= Quaternion.Euler(rotateDegrees);
isSpinning = true;
}
private void RotateToPrevious()
{
// set the previous texture slide
if(tex <= 0)
tex = maxTextures - 1;
else
tex -= 1;
if(!isBehindUser)
{
if(side <= 0)
side = maxSides - 1;
else
side -= 1;
}
else
{
side = (side + 1) % maxSides;
}
if(horizontalSides[side] && horizontalSides[side].GetComponent<Renderer>())
{
horizontalSides[side].GetComponent<Renderer>().material.mainTexture = slideTextures[tex];
}
// rotate the presentation
float yawRotation = !isBehindUser ? -360f / maxSides : 360f / maxSides;
Vector3 rotateDegrees = new Vector3(0f, yawRotation, 0f);
targetRotation *= Quaternion.Euler(rotateDegrees);
isSpinning = true;
}
}
I have managed to get the object to do this apart from it stops at each side of the object, but cant work out what part of the code is doing this.
I understand you ask for help finding which parts are involved in the rotation.
As such, I looked through the scripts and noticed 2 sections in the PresentationScript.
This part in the Update() method. Based on the code and the comments that are part of it.
// spin the presentation
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, spinSpeed * Time.deltaTime);
// check if transform reaches the target rotation. If yes - stop spinning
float deltaTargetX = Mathf.Abs(targetRotation.eulerAngles.x - transform.rotation.eulerAngles.x);
float deltaTargetY = Mathf.Abs(targetRotation.eulerAngles.y - transform.rotation.eulerAngles.y);
if(deltaTargetX < 1f && deltaTargetY < 1f)
{
// delay the slide
slideWaitUntil = Time.realtimeSinceStartup + slideChangeAfterDelay;
isSpinning = false;
}
This line in the Start() method is also involved.
targetRotation = transform.rotation;
A transform controls the position, scaling and as is relevant for this case, also the rotation of an object.

Categories

Resources