I Have started a new game.I have an enemy, and when the player is on a certain distance from the enemy, he attacks.My script works and the enemy follows the player, but despite the number I set there it's following the player.
I need the enemy follow only after being close enough to the player.
I have an empty object attached to the enemy and the script is on it.
I looked for the answer in unity community answers and find the script i use in this link https://answers.unity.com/questions/274809/how-to-make-enemy-chase-player-basic-ai.html
and also i have googled it but couldn't find any correct solution for it .
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AIController : MonoBehaviour
{
public int AttackTrigger2;
public Transform Player;
public int MoveSpeed = 4;
public int MaxDist = 10;
public int MinDist = 5;
void Update()
{
transform.LookAt(Player);
if (Vector3.Distance(transform.position, Player.position) >= MinDist)
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
if (Vector3.Distance(transform.position, Player.position) <= MaxDist)
{
//Here Call any function U want Like Shoot at here or something
}
}
}
}
I have no errors on my code, he does what i need but i need enemy stop following the player after my player is from a certain distance.
I'm guessing that the next answer in the forum you linked actually solves your problem. The problem is simply copying and pasting without understanding why something behaves like it should. In this case:
>= MinDist
Means that the enemy will follow the player as long as it's greater than or equal to MinDist, in this case 5. I'm guessing that you want is:
<= MaxDist
so that the enemy only follows if it's less than 10 away. If it's over 10 away, stop following.
You should change condition in first if case.
According to your code enemy will follow the player, if distance between them is grater than MinDist.
Replace >= with<=.
And I think you may have wanted something like this.
if (Vector3.Distance(transform.position, Player.position) <= MaxDist)//not MinDist
{
transform.position += transform.forward * MoveSpeed * Time.deltaTime;
if (Vector3.Distance(transform.position, Player.position) <= MinDist)//not MaxDist
{
//Here Call any function you want, like Shoot or something
}
}
Related
I'm a beginner. I'm making a ball game in Unity, in which ball have to avoid the collision with the obstacle. In the game, I'm increasing the ball speed in every 3 seconds. Everything's working fine, but in the middle of game, I noticed the ball starts shaking, the speed decreases, and the camera can't catch the ball. I attached physics material to all gameobjects, and made all frictions zero, but the ball is still shaking.
Here is the link of the my game and the problem. Have a look: https://youtu.be/TR4M5whweTk
Here is the script attached to the ball:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
public Text gameOverText;
public Text scoreText;
public bool isGameOver;
public float speeder;
public float Score;
Touch touch;
public float speedmodifier ;
public float speed = 5;
// Start is called before the first frame update
private void Awake()
{
isGameOver = false;
Score = 0;
if(PlayerPrefs.GetFloat("HighScore") == 0)
{
PlayerPrefs.SetFloat("HighScore", 0);
}
PlayerPrefs.SetFloat("Score", Score);
}
void Start()
{
speeder = 4f;
gameOverText.enabled = false;
speedmodifier = 0.01f;
// GetComponent<Rigidbody>().velocity = new Vector3(0,0,speed);
}
// Update is called once per frame
void Update()
{ if(speeder >= 0)
{
speeder -= Time.deltaTime;
}
if (speeder<= 0 && speed < 50)
{
speed++;
speeder = 4f;
}
Debug.Log(speed);
if (isGameOver == false)
{
Score++;
}
scoreText.text = "Score : " + Score ;
if (Input.touchCount >0 && transform.position.x >= -3.5f && transform.position.x <= 3.5f)
{
touch = Input.GetTouch(0);
transform.Translate(touch.deltaPosition.x * speedmodifier,0,0);
}
else if(transform.position.x > 3.5f)
{
transform.position = new Vector3(3.49f,transform.position.y,transform.position.z);
}
else if(transform.position.x < -3.5f)
{
transform.position = new Vector3(-3.49f,transform.position.y,transform.position.z) ;
}
if (Input.GetKey(KeyCode.RightArrow) && transform.position.x < 3.5f)
{
transform.Translate(Vector3.right*speed* Time.deltaTime);
}
if (Input.GetKey(KeyCode.LeftArrow) && transform.position.x >-3.5f)
{
transform.Translate(Vector3.left*speed* Time.deltaTime);
}
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "enemy")
{
isGameOver = true;
StartCoroutine("Wait");
GetComponent<MeshRenderer>().enabled = false;
gameObject.GetComponentInChildren<TrailRenderer>().enabled = false;
gameOverText.enabled = true;
if(PlayerPrefs.GetFloat("HighScore") < Score)
{
PlayerPrefs.SetFloat("HighScore", Score);
PlayerPrefs.SetFloat("Score", Score);
}
else
{
PlayerPrefs.SetFloat("Score", Score);
}
}
}
IEnumerator Wait()
{
Debug.Log(" My HighScore is : " + PlayerPrefs.GetFloat("HighScore"));
Debug.Log(" Score is : " + PlayerPrefs.GetFloat("Score"));
yield return new WaitForSeconds(3f);
SceneManager.LoadScene(1);
}
}
As BugFinder pointed out you are actually not moving the ball with physics, but just teleporting the ball with Transform.Translate which might be affecting the shacking issue, the other possible problem is that your ball speed might be varying due to a collision with the road, have you tried making the road RigidBody to Kinematic? so it won't affect the speed of the ball
OK you SHOULD NOT be using unity phsyics for this.
It's a "raster" game (and that's fun).
remove all physics everything. completely remove rigidbody, collider, etc
simply move the ball and/or scenery using a calculation each time.
(It's basically just frame time * speed, obviously.)
(Note, you can use strictly triggers - if you want - simply to know if the "ball" is near a "stick". But you can do that with 1 line of code, really no need for colliders/etc.)
Your Question
I just want to make sure that I am understanding your question correctly first, I believe you are asking for a way to prevent the ball from shaking during the game. (Let me know if this is incorrect, if so I apologize). From what I have gathered, this does not seem like a code based issue
Collision Detection
In unity, the rigidbody component has a field named 'Collision Detection' and this is set to discrete by default. This means that unity will look in direction of travel for a possible collider every now and again. That is an okay method to use when trying to save computer resources, however when in constant contact or at high velocities it is best to use the 'continuous' mode. This will check for a collision every physics update which occurs every physics time-step.
Colliders
Colliders in unity are a little finicky. Most notorious are mesh colliders as they have to be more heavenly processed/calculated. Using a box collider for your ground might give more accurate physics results.
Other Solutions
Whilst looking at your game video you published on YouTube, it looks like using physics may not be able to work. Since you are only traveling left, right, and forward globally, I would suggest implementing a movement script that uses an object's transform component instead of physics. This will be less resource intensive and will save further debugging headaches in the long run.
I'm new to Unity and coding and am putting together a small project to help me get used to it. I have a problem with a particle system though. What I want it to do is to play two-particle systems at the same time when I hold down the spacebar and then stop when I let go, but the smoke particle system only plays after I let go of the spacebar and stops when I hold it down again. The flame particle system doesn't stop after I let go of the spacebar either. Can anyone help?
Here is the code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rocket : MonoBehaviour
{
public float fuel = 500f;
public float speed = 100f;
public Rigidbody rb;
public ParticleSystem flame;
public ParticleSystem smoke;
void Start()
{
flame.Stop();
smoke.Stop();
}
void FixedUpdate()
{
if (Input.GetKey(KeyCode.Space) && fuel > 0)
{
rb.AddForce(Vector3.up * speed);
float fuelUse = fuel-- * Time.deltaTime;
flame.Play();
smoke.Play();
}
}
}
You need to put an else after your if.
In this way when you aren't pressing space it will always stop, but will start when you press space and fuel is >0.
A great thing you can do in this cases is to put some Debug.Log() inside the if to check when it's playing so you can find other problems.
For example you can add the else with flame.Stop() and smoke.Stop() and put inside it a Debug.Log("stop") and inside the if a Debug.Log("play") so in the console you will always know what is happening and what is wrong
GetKey function resetting ur particle systems per frame so u can't see till release spacebar
if (Input.GetKeyDown(KeyCode.Space) && fuel > 0)
{
isPressed = true;
flame.Play();
smoke.Play();
}
if (isPressed && fuel > 0)
{
rb.AddForce(Vector3.up * speed);
float fuelUse = fuel-- * Time.deltaTime;
}
if (Input.GetKeyDown(KeyCode.Space))
{
isPressed = false;
flame.Stop();
smoke.Stop();
}
I am in the process of creating a 3D single-player FPS and am currently working on the movement of the enemies in the game. As this is my first game and doesn't know C# that much I followed a tutorial to do this:
https://www.youtube.com/watch?v=_Z1t7MNk0c4
the tutorial was for 2d but said that it would wor for 3d as well
here is the script that I have
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movment_shoot : MonoBehaviour {
public float speed;
public float stoppingDistance;
public float retreatDistance;
private Transform player;
void Start() {
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update() {
if (Vector2.Distance(transform.position, player.position) > stoppingDistance) {
transform.position = Vector2.MoveTowards(transform.position, player.position, speed *
Time.deltaTime);
} else if (Vector2.Distance(transform.position, player.position) < stoppingDistance &&
Vector2.Distance(transform.position, player.position) > retreatDistance) {
transform.position = this.transform.position;
} else if (Vector2.Distance(transform.position, player.position) < retreatDistance){
transform.position = Vector2.MoveTowards(transform.position, player.position, -speed *
Time.deltaTime);
}
}
}`
I have not added the shooting part yet when I run the game the enemy I have applied the script to teleports to a location just outside the terrain whilst the game is still playing if you move the enemy along if you try and move it along the x or z axes it will only move along x then go back to the original position if you move it along the y it will let you but then move back to its original position please help with anyways I can make this work correctly.
Pay attention with vectors in unity: lower dimensionality vectors operations "cut out" excess dimensions.
Your problem is that the Z is completely left out of the equation 😉.
You just need to use the methods of the Vector3 class rather than Vector2.
Since the android should fly or move in the air too I guess I should also use physics too ? Not sure.
I added some spheres as waypoints and I want the android to move between them randomly including random range of movement and rotation speed. For example 1-10 range randomly speed for both movement and rotation.
Now what it does when I'm running the game the NAVI (1) is just moving in rounds none stop on small area not sure why, But it's not moving smooth between the spheres.
The idea is to make the NAVI droid to act like it's out of order.
This is screenshot of the NAVI (1) and it's inspector:
This screenshot is of the Waypoints attached to it Waypoints script:
This is the Waypoints script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Waypoints : MonoBehaviour
{
public Transform objectToMove;
public float moveSpeed = 3.0f;
public float rotationSpeed = 3.0f;
public GameObject[] waypoints;
public int currentWP;
private void Awake()
{
}
private void Start()
{
currentWP = 0;
}
private void Update()
{
if (waypoints.Length == 0) return;
var lookPos = waypoints[currentWP].transform.position - objectToMove.position;
lookPos.y = 0;
var rotation = Quaternion.LookRotation(lookPos);
objectToMove.rotation = Quaternion.Slerp(objectToMove.rotation, rotation, Time.deltaTime * rotationSpeed);
objectToMove.position += objectToMove.forward * moveSpeed * Time.deltaTime;
}
}
You are never changing currentWP. That means at every frame, you're rotating toward the same nav point and moving the droid back towards it.
You have to change the currentWP only when the droid reaches it. Use OnTrigger between the target nav point and the droid.
You can do it something like this .
//for example you've got 5 waypoints
currentWaypoint = Random.Range(1, 5);
Hope it helps
I'm trying to destroy my player whenever the explosion particle effect comes within a certain distance of the player. Here is what I tried and this script was added to my explosion prefab:
using UnityEngine;
using System.Collections;
public class ExplosionController : MonoBehaviour {
GameObject playerObj;
Transform player;
Transform playerPos;
// Use this for initialization
void Start () {
player= GameObject.FindGameObjectWithTag("Player").transform;
playerObj = GameObject.FindGameObjectWithTag("Player");
}
void Update()
{
float playerDis = Vector3.Distance(player.position, transform.position);
if (playerDis == 4)
{
Debug.Log(playerDis);
Destroy(playerObj);
}
}
}
My Debug attempt at the bottom condition didn't yield any console output, so I assume I made a mistake in the playerDis variable.
I can't comment because I don't have 50 reputation points yet, but I would change your
if (playerDis == 4)
to
if (playerDis <= 4)
This should catch any collisions that may not exactly equal 4.00.... because Update may not be called fast enough.
With the keyword in your question being 'within'.. You should look for a distance from 0 to 4. So:
void Update()
{
float playerDis = Vector3.Distance(player.position, transform.position);
if (playerDis <= 4)
{
Debug.Log(playerDis);
Destroy(playerObj);
}
}
I assume that your distance is never exactly equal to 4, considering that Vector3.Distance() returns a float.