- Home /
Advice on my Ship AI...
I am trying to make a space trek game and have got to the point that I need to make a ship AI so I looked around and tried this code for following the player which will at some point shoot at me.
using UnityEngine;
using System.Collections;
public class AI : MonoBehaviour
{
public Transform target; //the enemy's target
float moveSpeed = 3; //move speed
float rotationSpeed = 3; //speed of turning
public Transform myTransform; //current transform data of this enemy
void Awake()
{
myTransform = transform;
}
void Start()
{
target = GameObject.FindWithTag("[Ally] Excelsior").transform; //target the player
}
void Update()
{
//rotate to look at the player
myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed*Time.deltaTime);
//move towards the player
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
}
}
Problem is that it follows my ship with the front up in the air looking strange as it comes at me lol What's happening? I don't really have any idea what a Quaternion is… any other advice since I don't want it to run into me but rather come at me and orbit me till I run and it follows. Does that make any sense? Kind of like in STO...
You should work on easier games. This might be a bit too hard for your level. Work on something like a sidescroller or a top down game. Dont directly jump into these huge games. Also, take a look at this: http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.html
Please, please, please read it carefully. Very useful
I have to disagree. Working on 2D games will not necessarily help learning 3D geometry.
what part of your ship is oriented with the y and x axis. you may just need to change the local orientation of your ship. Here is the official documentation of Quaternion.LookRotation [1]: http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.LookRotation.html
Answer by Carbongrip · Dec 13, 2013 at 10:12 PM
I fixed it lol!
transform.LookAt(target);
Vector3 eulerAngleOffset = new Vector3(270, 0, 0);
transform.Rotate(eulerAngleOffset, Space.Self);
// move forward
transform.Translate(0,-moveSpeed * Time.deltaTime,0);//move the ship
needed to add this so that it was at the 270 rotation the ship was at lol!
Vector3 eulerAngleOffset = new Vector3(270, 0, 0);
transform.Rotate(eulerAngleOffset, Space.Self);
Answer by Tomer-Barkan · Dec 05, 2013 at 07:51 AM
Your script is using Slerp incorrectly. You keep moving each frame a fraction of what remains of the rotation. That means you'll never reach. Think that you're moving halfway towards your destination every frame. Will you ever reach it? No. You always move half of what remains, so there will always remain the other half...
Try this instead:
void Update()
{
// rotate towards player
Vector3 toTarget = (target.position - myTransform.position).normalized;
myTransform.forward = Vector3.RotateTowards(myTransform.forward, toTarget, float rotationSpeed * Time.deltaTime, 0);
// move towards the player
myTransform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
}
That still acts the same way it did before… when I look at the ship co$$anonymous$$g at me its top side is co$$anonymous$$g at me ins$$anonymous$$d of looking like a regular ship with the front edge co$$anonymous$$g at me. So the front edge is facing up in the room with the top side co$$anonymous$$g at me and the back side behind whats co$$anonymous$$g at me if that makes any sense, its hard to explain. Also how can I make it not get to me and rapidly spin around in a circle? I would say once it gets a certain distance it should orbit me till I run and it follows sort of thing… If you remember when you helped me with shield we had a hard time with getting the right facing hit so you had me just change the labels around to match.
If you see it's top side, it might be that the mesh is not facing the forward (positive Z axis). Try dragging the prefab into the scene, set all rotations to zero, and see which direction it is facing.
About the orbit, it's been discussed a few times. One way to go is this thread: http://answers.unity3d.com/questions/428548/trying-to-move-an-object-in-an-arc-around-the-play.html.
There's also this thread http://answers.unity3d.com/questions/235105/orbit-player-around-center-point.html which I like. Create an empty GameObject and place it where your player is. $$anonymous$$ake your AI a child of this object. Then start rotating the object, and the AI will automatically circle around.
Ok so realized that all my ships have a rotation set so they look correctly in game so how do I fix the script to compensate for the x rotation of 270 since all ships have that rotation? This is why we had to change values to match in the shield script. Also there's only a x rotation the y and z are 0.
If your ship is rotated 270 on the X, so that it will face the positive Z axis after the rotation, that means that without rotating it is facing up. So it's nose is always pointing to transform.up.
So ins$$anonymous$$d of using myTransform.forward, use myTransform.up.
If I'm wrong, it's transform.down, but I'm pretty sure it's up.
tried up and it didn't work correctly so I tried down but gives errors…
void Update()
{
// rotate towards player
Vector3 toTarget = (target.position - myTransform.position).normalized;
myTransform.down = Vector3.RotateTowards(myTransform.down, toTarget, rotationSpeed * Time.deltaTime, 0);
// move towards the player
myTransform.Translate(Vector3.down * moveSpeed * Time.deltaTime);
}
Answer by tanoshimi · Dec 05, 2013 at 07:26 AM
Quaternion.LookRotation() takes two parameters which describe the "forward" and "up" vectors of the desired rotation.
In the following line, you're setting the "forward" direction equal to the vector between the target and the the current position, which seems ok, but you're setting the "up" direction to be equal to rotationSpeed*Time.deltaTime, which seems a little funky...
Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed*Time.deltaTime);
Try replacing it with:
Quaternion.LookRotation(target.position - myTransform.position), Vector3.up);
Which will set the forwards direction while keeping "up" pointing up the global y axis.
Answer by JPB18 · Dec 08, 2013 at 12:10 AM
Well, usually AI is made using beaviour trees (FSMs), in wich you must define several conditions for a certain action to happen. And that usually includes a lot of pen and paper.
I do happen to be doing a Star Trek based game (named Star Trek: Broken Mirror), and I remember we had to do a lot of stuff before even working on things like AI, so we could gain eough experience to tackle that problem. Maybe you should also do the same... Tackle things like ship movement, weapon targeting, create a solid movement system with well defined interfaces (public methods, that is), and some other things like a friend-or-foe system, and then you might be reaady to handle the AI.
You should also read something about the theme... Unity Gems has this fine series of tutorials that might hep you with that:
Here's the decision tree schematic... Start by planing out something like this, working on how your AI will perceive the environment, and how it'll react to it... Also, I'd recomend you'd take a look at Finite State $$anonymous$$achines.
Thanks that helps me a bit good idea of what I need to be doing for the ai, so besides that do you know how to add tilt to a ship as it turns or have a link to the place you downloaded the sovereign you are using?
Well, I got the model from the Bridge Commander Community and then used nifSkope to transform the model from nif to obj. After that I passed it through 3Ds $$anonymous$$ax (or $$anonymous$$aya, or Blender with FBX and OBJ export plugins, w/e) "fixed" some model issues there might exist, and then exported it as a FBX.
Your answer
Follow this Question
Related Questions
Prevent 2D spaceship going out the screen 1 Answer
Distribute terrain in zones 3 Answers
still have some problems with c# AI 1 Answer
Multiple Cars not working 1 Answer
Freelancer of Freespace type Enemy Ai 2 Answers