#AI movement
1 messages ยท Page 1 of 1 (latest)
the capsule will need a NavMeshAgent component
check
and you'll need a script to set the navmeshagent's destination variable
there is a method i think
I think it's destination
leme explain what im doin here
so its a static turret defense game
that black spot on the hill, is the player
you can use setdestination
just so yall know
to make the navmesh go to a certain position
i have it
i need to code it in?
everything you can do with a navmeshagent is at my link ๐
yes
how come you put ๐ after most of your messages lmfao
yeah, you'll need to make an 'enemymovement' script
discordinvader always does this . . .
habit - been typing for so long it just kinda happens
me neither
does the method need to be called in start? or update?
I do the dashes in my sentences for punctuation too - no idea where that came from
you want it to happen every frame
if it only happens for one frame then it wont move.
yeah, every frame, since your player position might change
everything is in update pretty much
things that you only want to happen once
is in start or awake
the players position does not change, but the rotation does
so getting a component
still that needs to happen every frame
one frame is one time
yeah
its only for like what is it 1/60th of a second
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
SetDestination(506.6,75.8,652.6);
}
}
if you are at 60 fps
i know i did this wrong
did u ever reference the navmeshagent
is it just me or do dictionaries suck
they do.
i cant figure this shit out
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
SetDestination(506.6,75.8,652.6);
}
}
oh wait
Some scripts have compilation errors which may prevent obsolete API usages to get updated. Obsolete API updating will continue automatically after these errors get fixed.
it wont star tnow
is this even an error
compilation errors - I think for this one, it'd be something like "SetDestination doesn't want and doesn't like three floats, you gotta feed it a Vector3"
u never reference it
NavMeshAgent agent;
the navemshagent
where do u get the instance of it
you have the component not the instance
NavMeshAgent agent;
oh
ffs
how do i get the instance?
Check out the Course: https://bit.ly/3i7lLtH
Learn 5 different ways you can connect your gameobjects in Unity. Ranging from direct references & singletons to scriptableobjects and injection.
More Info: https://unity3d.college - (and where you can submit your own questions)
Join the group: http://unity3d.group
either reference via insepctor
or getcomponent those r the main ways
no those r just 5 ways
it teaches u it
i dont wanna just give u the answer bc u wont learn
this video is very helpful
basically think of it this way
you got a token from a prize right?
the token says you can pick out a dog
is the token the dog you picked out? @haughty basin
no, the token is a the token?
yes
you use a token and then you get the dog with it
a dog is an instance
you can pick which instance to get with the token
the token is the navmesh variable
so basically you pick out which navmesh you want to assign to that variable
do u get it?
No not at all
ok i have an idea
so...
i was given this exact lesson
do you know what a class is
what kind of class
in programming
yeah, its a thing where you do stuff. it can be public, private, or protected.
yeah basically think of stuff inside of a class like instructions of a cat
I'll give an example of my enemy movement script, it's pretty simple, just ignore all the animation stuff
inside a class you pick the fur color
you pick how long the claws are
you pick the breed and color eyes
using UnityEngine.AI;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
public Transform goal;
public Animator m_animator;
public float normalspeed;
public bool isactive = false;
public bool isattacking = false;
public attacktriggerscript atkref;
void Start()
{
m_animator.Play("bushmanidle");
}
void OnTriggerStay(Collider collider)
{
if (collider.tag == "Player")
{
m_animator.SetBool("aggro", true);
NavMeshAgent agent = GetComponent<NavMeshAgent>();
agent.destination = goal.position;
isactive = true;
if (!atkref.isattacking)
{
GetComponent<NavMeshAgent>().speed = normalspeed;
}
}
}
void OnTriggerExit(Collider col)
{
if (col.tag == "Player")
{
m_animator.SetBool("aggro", false);
GetComponent<NavMeshAgent>().speed = 0;
isactive = false;
atkref.isattacking = false;
}
}
}```
you following @haughty basin
Yeah
so what an instance is
GetComponent<NavMeshAgent>().speed = 0;
its using the classes basically
so an instance of a class
is
lets say you create a class with black fur and blue eyes
thats an instance of cat
you can make another instance of cat with blue fur and black eyes
and so forth
an instance is a cat
i know that stuff
a class is an instruction
instance is a literal cat
if you have two instances of that class
you have two of those exact instances
basically you have a variable
you need to tell the variable the instance you want to manipulate
that is why u need getcomponent
you need to get the instance of the cat to change
so lets say you have instances cat 1 2 and 3
if you get instance 2
then you can use the variable that u store the instance in to change it
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
GetComponent<NavMeshAgent>();
agent.SetDestination(506.6,75.8,652.6);
}
}
u want it in start
bc u only want to retrieve the instance once
you only need to tell the variable which cat it is once
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
public NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
agent.SetDestination(506.6,75.8,652.6);
}
}
well you need to pick which component
using GetComponent this way will -only- work if this script is on the same gameobject as the navmeshagent
so basically what you can do is use [serializefield]
in the inspector
you can drag in the correct instance
you're really losing me
with get compoenent you wanna do agent = object.getcompoentn<navmeshagent>();
watch the video i sent u
I have it going.
just change GetComponent<NavMeshAgent>(); into agent = GetComponent<NavMeshAgent>();
i did
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
[SerializeField]
public NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
agent = object.getcompoentn<navmeshagent>();
}
// Update is called once per frame
void Update()
{
agent.SetDestination(506.6,75.8,652.6);
}
}
then as long as enemymovement is on the same object as the navmeshagent, that should get the reference
You donโt need grtcompoent if you have serialefield
Think about it logically
You are trying to retrieve the instance
You donโt need to do it twice
What object is ur backwash navmesh
idk wtf i was doing there lol
sorry about that
๐
but [SerializeField] can't just be a magic answer, can it?
it's a different way to reference it
normally, the easiest way to define a variable, is just to drag the gameobject with the relevant component into an inspector window
but in this case, I think this is an even eeeeasier way
All you need to do is drag in the instance in the inspector
yeah
you'd have to add serializefield, but you don't need to do that at all
GetComponent, without an operator, references the parent gameobject
Either
but i can't have both???
agent = object.GetComponent<NavMeshAgent>();
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemyMovement : MonoBehaviour
{
[SerializeField]
public NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
agent.SetDestination(506.6,75.8,652.6);
}
}
im getting the same eror
that "NavMeshAgent" can't be found
but i put in serializefield
serializefield just makes it so it shows up in inspector, to drag the object into
sounds like you had a bug I experienced today with compilation errors, add public int test;
up at the top, a new declaration
save, go back to unity
and it should be fixed
then you can remove the int test ๐
its still showing an error btw
The type or namespace name 'NavMeshAgent' could not be found
im reloading into unity
up at the very top, you need to have using UnityEngine.AI;
along with the other libraries.
each error is a clue to why its not working ๐
Yeah but the clue is in english, but its not really in english.
i don't understand a single error
why cant it just tell me what is wrong
instead of just saying big shit to make it look smarter
No overload for method 'SetDestination' takes 3 arguments
see what tf is this
heh
agent.SetDestination(Vector3(506.6,75.8,652.6));
nah, you'll need to make a new one - so on the line right before it:
Vector3 vec = new Vector3 (506.6, 75.8, 652.6);
and then change to agent.SetDestination(vec);
void Start()
{
}
// Update is called once per frame
void Update()
{
Vector3 vec = new Vector3(506.6,75.8,652.6);
agent.SetDestination(vec);
}
looks good
oshit it wants a double -_-
stand by ๐
oh wait no I know the problem
any fractional integer, like, a non-whole number, needs to have f after it
to define it as a float
not sure why
๐
i cant get the bullet from the guns to disappear if they hit something
gameObject.Destroy();
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class destroyBullet : MonoBehaviour
{
void OnCollisionEnter(Collider coll) {
if (coll.gameObject.name == "Terrain") {
Destroy (gameObject);
}
}
}
oh wait yeah yours is actually correct mine is probably wrong
yeah yours is right, mine is wrong -
here it just says..
I expect you are having collision issues
Oh, thats the error?
yeah
change Collider to Collision
see, I was going to go off on a tangent about collision troubleshooting, but boom, there it is, in the error
they still don't destroy
no errors now?
small victories ๐
well it looks like we get to go into collision troubleshooting after all ๐
inside the if, let's put Debug.Log(coll.gameObject.name);
save and test ๐
nothing in console
move it to up before the if
nothing in console
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class destroyBullet : MonoBehaviour
{
void OnCollisionEnter(Collision coll) {
Debug.Log(coll.gameObject.name);
if (coll.gameObject.name == "Terrain") {
Destroy (gameObject);
}
}
}
a sphere collider, yes
a rigidbody?
try making the bullets slower, could be that its too fast
there's special things you gotta do for super fast projectiles
unity default physics can't keep up
slower, slower
slow em right down, it's for a test, remember
not for.. gameplay finishing
see thats what i did originally
and then you can change Collision back to Collider
we have come full circle
haha well, this problem was soooooo far down the list
finally
I didn't expect you to have it set to be a trigger collider ๐
i think i did that bc i want the enemies to die upon contact with the bullet
and my mind thought trigger
a trigger collider is basically just a collider that doesn't.. physically collide with stuff - it won't like, use unity physics to bounce off of other colliders
can i not make the bullets faster now?
but that doesn't matter in this case, it's perfect for registering collisions with terrain
well, try it out - remember there'll be a limit though
1500 doesnt work
if the bullet's collider passes completely through the terrain's collider within a frame, no collision will be registered
the trick I mentioned, involves shooting a raycast out from the front and back of the bullet, and adjusting the bullet's position appropriately when the ray touches a wall
1 sec
It works though, kinda
sometimes the bullets go through the gruond
but it doesnt have to be perfect
this is for a school project
you could have them destroy themselves on a timer
its not last second, but it kinda is
after like 20 secs
good idea
but timers are weird
timr += Time.deltaTime;
if(timr >= 0.1f)
{
timr = 0;
if (Input.GetButton("Fire1")){
GameObject ball = Instantiate(projectile, transform.position,transform.rotation);
ball.GetComponent<Rigidbody>().AddRelativeForce(new Vector3(0, 0,-launchVelocity));
}
}
}
}
im gonna take a break too, do you wanna come back in 20?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bleeddecay : MonoBehaviour
{
public float bleedtimer = float.NegativeInfinity;
// Start is called before the first frame update
void Start()
{
bleedtimer = 0f;
}
// Update is called once per frame
void Update()
{
bleedtimer += Time.deltaTime;
if (bleedtimer >= 2) {
Destroy(gameObject);
}
}
}
there's a simple one ๐
if that script is on a gameobject, the object will destroy itself 2 seconds after it is created
yeah thats seconds - increase it if you want
lol was just thinking, this'll be the second time I've helped a student try and reach a late deadline last minute ๐
what are the assignment parameters?
alright im back
its not huge
just six thigns i have to do
X1. Game audio (sounds, music, etc.)
X2. Game Physics (RigidBody, Area2D, KinematicBody2D, Ray-casting, etc.)
X3. Game Math (vectors, Matrices, Curves, Paths, etc.)
4. Game Animation
5. Game Score
6. Player lives
X7. Collision detection
X8. User input (keyboard, mouse, microphone, touchscreen, etc.)
9. Saving a game
10. Loading a previous game
11. Pausing and resuming a running game
12. Networking
13. Multiplayer
14. Virtual Reality
the ones with x's are ones i have done
@hexed frost
it still deletes pretty early
so you need to do six of the 14?
yaeh
and ive done 5
so its not really last minute
i just have to give a presentation on this tomorrow
this entire game is based off of another game that was popular in the early 2000's
reminds me of 'a perfect tower'
Digital Fusion Entertainment presents the DESERT WAR - third game in the classic BEACH HEAD series - Gameplay Video.
(Music Credit - Snake Charmer by Synapsis freemusicarchive.org/music/synapsis)
i played this shit all the time when i was a kid
i plan to add just infantry units to kill (represented by the capsules
right now im trying to get the bleedtime to work right
its killing off the bullets way too early*
did you increase the time?
what did you increase it to?
30
they still die out in 2 seconds
or around 2.5 sceonds
its har dto sound
its hard to count*
3 seconds
lets see the script ๐
here
the version you are using
you probably set it in the wrong place, let's see your script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bleeddecay : MonoBehaviour
{
public float bleedtimer = float.NegativeInfinity;
// Start is called before the first frame update
void Start()
{
bleedtimer = 0f;
}
// Update is called once per frame
void Update()
{
bleedtimer += Time.deltaTime;
if (bleedtimer >= 2) {
Destroy(gameObject);
}
}
... nothing is changed there
exactly
i changed the bleeddecay timer
it was negative infinirt
infinity
but i changed to 30
in that script, change if (bleedtimer >= 2), into 30
negativeinfinity is just a placeholder, that script sets it to zero at start
no, change the 2
into 30
the 2 is the two seconds...
oh ok
-_-
im sorry, i didn't know what it was there for
well, I was right, you did set it in the wrong place lol
so what you thinking for the last feature? I recommend against saving and loading, thats what I spent like ten hours today smashing my head against
well, i gotta make the enemies die, or else it isnt really a game
then.....
maybe pausing
pausing seems a lot easier
pausing pretty easy yeah ๐
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public static class gamesaver
{
public static string directory = Application.persistentDataPath + "/SaveData/";
public static string filename = "SaveData.txt";
public static void Save(SaveObject so)
{
string dir = Path.Combine(Application.persistentDataPath, directory);
if (!Directory.Exists(Application.persistentDataPath))
{
Directory.CreateDirectory(Application.persistentDataPath);
}
string json = JsonUtility.ToJson(so);
File.WriteAllText(dir + filename, json);
Debug.Log(json);
}
public static SaveObject Load()
{
string fullPath = Path.Combine(Application.persistentDataPath, directory, filename);
SaveObject so = new SaveObject();
if (File.Exists(fullPath))
{
string json = File.ReadAllText(fullPath);
so = JsonUtility.FromJson<SaveObject>(json);
}
else
{
Debug.Log("No save file");
}
return so;
}
}```
there's 1/4 saving scripts I wrote earlier
pure... pain
and the damn thing doesn't even work properly, I'm back at er tomorrow to try and fix it
well i cant help, but i can be a mascot
lol
well, making the enemies die should just be as simple as..
should that go in the bullet script, or the enemy script?
on the enemies
then you can have OnTriggerEnter checking for the name/tag of the bullets
the collisions of the enemies should be trigger?
I find trigger collisions more reliable
alright they are triggers now
no wait
you are confusing Collisions with Colliders
change the enemy's collider back to non-trigger
done
the 'collision' refers to the interaction event between two colliders
only one of the two needs to be trigger for OnTriggerEnter
one of the two colliders making the collision needs to be trigger, in order to use OnTriggerEnter
since the bullet already is, the enemy doesn't need to be
right
so the kill command should be on the bullet
to check if its an enemy?
right?
nope, on the enemy, to check if its being hit by a bullet, unless you want the bullets to.. generate references to the enemies they hit, in order to destroy them ๐
oh ok
see what im sayin? the bullet won't know which enemy to destroy ๐
if(enemyhitbybullet){
die();
}
more like:
void OnTriggerEnter(collider col)
{
if (col.tag == "bullet")
{
do the thing
}
}
I use tags for everything ๐
but you said to not make the enemy collider a trigger
I don't see how I have contradicted that
void OnTriggerEnter
yeah, one of the colliders needs to be trigger, doesn't matter which one
in this case its the bullet
oh ojk
something aint right
i feel like im close
void OnTriggerEnter(Collider col){
if(col.tag == "bullet"){
Destroy(gameObject);
}
}
in order to use .tag, you need to have the correct ... tag on the object
know how to set a tag?
no because they are named like.. clonesomethingsomething, right
yeah
because they are instantiated clones of a prefab
so in the inspector, in unity, in the top right, there's a dropdown for tags
down at the bottom, create a new one, called bullet
then, select the bullet prefab, and set its tag to that
done
test time ๐
probably a little trickier than you think - if you want the enemy to emit the death sound, you can't flat out destroy the gameobject, because the sound is on it ๐
you'd have to.. disable it's meshrenderer first, play the sound, then destroy it
on timers ๐
ezpz ๐
now pausing
yer kidding
and you turn it off by setting it back to 1
I was going to post my pausecontroller, but.. it has a whole bunch of other features
well this should just be easy as hel
if get button down pausebreak
then time scale 0
if (Input.GetKeyDown(KeyCode.Escape))
{
if (!deathtrackerref.deathactive)
{
if (menuactiondelay > 0.5f)
{
if (!ispaused)
{
pausemenuanim.Play("pausefadein");
ispaused = true;
menuactiondelay = 0;
Time.timeScale = 0;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
else
{
pausemenuanim.Play("pausefadeout");
menuactiondelay = 0;
Time.timeScale = 1;
ispaused = false;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
}
}```
I have a pause menu after pausing, so I run a bunch of animations, and need a delay so people can't just spam esc and get it caught mid menu-open or close
so you could basically take out evvvvverything except if input, if ispaused, and the two timescale and ispaused settings
and that'd be a wrap
if (Input.GetKeyDown(KeyCode.Escape))
{
if (!ispaused)
{
Time.timeScale = 0;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
ispaused = true;
}
else
{
Time.timeScale = 1;
ispaused = false;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
now if you want to -do- anything involving time while timeScale is 0, you can use unscaledTime
that looks good
put it in an update method and try er out ๐
is cursor methods still a part of that?
if you want, they do what they say ๐
lol 'deleting'
btw it doesn't work
what doesn't work
lesse current script
leme try something
whole thing
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pauseController : MonoBehaviour
{
public bool ispaused;
// Start is called before the first frame update
void Start()
{
ispaused = false;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (!ispaused)
{
Time.timeScale = 0;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
ispaused = true;
}
else
{
Time.timeScale = 1;
ispaused = false;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
}
}
better to set it to false right at the top actually
public bool ispaused = false;
then you don't need that in start
escape doesnt work
oh im a dumbass
one second
where would i put the pausecontroller script?
on an object that will be active in the scene when you want to pause
I stick all my like, placeless scripts, onto my canvas
hmmm.. well all it is supposed to do it stop the game, so I don't know what you mean by it works
how does it work..
(but also not work?)
^
so.. it's not pausing
hmmm
I.. have no idea.. it works for me
stops everything dead, I've used it identically for last three projects
holy hsit
now it works?
WTF?
ohhh
OHHH
IT DOES WORK
IT JUST THE TURRET STILL MOVES
using UnityEngine;
using System.Collections;
public class CameraScript : MonoBehaviour {
public float speedH = 2.5f;
public float speedV = 2.5f;
private float yaw = 0.0f;
private float pitch = 0.0f;
void Update () {
yaw += speedH * Input.GetAxis("Mouse X");
pitch -= speedV * Input.GetAxis("Mouse Y");
transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);
}
}
try changing it to FixedUpdate
im laughing hard
its not important
the turret cant fire
when paused
and also the enemies stop
well, you can get a reference to the pausecontroller in camerascript, and only do the movement if ispaused = true
er I mean false
nah
this is good
it is complete
but i gotta add WAY more enemies
so copy and paste time
why not make a spawner ๐
similar to how you make the bullet, just without adding velocity
too many navmeshagents will cause pathfinding problems ๐
thats why we gotta kill them
goal of game: prevent performance drops
๐
if you want 'flying' enemies, move the enemies collider and renderer way up above the navmeshagent ๐
they'll still technically be moving the same, with the navmeshagent on the ground, but it'll look like they are, however far above it you set them
oh well, id want them to be faster and stuff
btw, none of these enemies hurt the player
Hmm I can't tell if they are coming towards the player at all
they are
they just slow
did you want them to hurt the player?
i mean, whats a game if you cant lose?
welp, you'll basically do the exact same thing as the bullet killer, but with a script on the player, looking out for tag "enemy"
i dont think there even is a player value]
well, it'll need a collider
might as well make it trigger, so you can use the exact same technique
alright
also, Destroying the player won't really result in some kind of game end - I think you'll need to.. pause the game, display a message, and have a button to restart ๐
ill just send it back to the main menu
and if we're talking essential game elements, gonna need a score too ๐
if we are gonna go this deep, then i might as well add the flying enemies
and stuff
shrug I'm about off to bed
I'm usually working on my game from like 6am-6pm, then either bumming around discord or playing league in the evenings
ill just add the game over stuff
then ill wrap it up
youve been a big help.
ill refer back to this thread later to learn more
glad to help ๐
.... meh ๐
..nevermind then .-.
you can, I don't really want it though ๐
ok
๐
but yeah, you can for sure dm me, add as friend, join my discord
I'm pretty friendly ๐
I'm somewhat new to Unity and yesterday started messing around with NavMesh.
I want the enemy to follow the player if it can, which works. But when the player is unreachable and the enemy can't see the player through a raycast, I want to set the enemy's priority to instead of following, it'd try and get a view of the player for projectiles.
Wdym you want it to look at the player?
Sorry, basically, letโs say the player is on a platform the enemy canโt get to. Instead of the enemy just walking underneath or to the wall of the platform and stopping, I want it to adjust its position to get a view of the player, like walking away from underneath the platform so it can see it, for example to allow the enemy to shoot projectiles at it while it canโt reach the player
I see. Well you can check if the enemy can see the player or not. You need to be more specific do you want the enemy to come closer to look or maybe just like jump to see it
I donโt need it to jump, no not come closer, just walk into view of the player if the views obstructed really, I can give a better example once I get home if you need
I have an idea. What if you shoot a ray from the player in the direction of the enemy. Then go towards the ray to get in view. What do u think of that?
Actually wait that donโt work
Let me think
Using a raycast is onto something Iโm sure, I have one set up already going from player to enemy, just donโt know how to handle the enemy walking back into view after itโs view is obstructed, thatโs the difficult part
What you want is so difficult
Why canโt it just move toward the player until itโs in its sights. Then stop the enemy?
because if the enemy were to be under this platform im standing on it wouldnt be able to do anything to shoot me, it'd have to back up from under it
well isnt that true?