JScript -- Unity transform.eulerAngles.y not Working - unity3d

So last week I started working on an RPG and I've started working on the enemy AI and it should rotate to it's target but it doesn't. What I did is for the enemy I created a child object and put a script that rotates it to the target, then in the enemy script I did this:
if(transform.eulerAngles.y > rotTracker.transform.eulerAngles.y) {
transform.eulerAngles.y -= 2 * Time.deltaTime;
}
if(transform.eulerAngles.y < rotTracker.transform.eulerAngles.y) {
transform.eulerAngles.y += 2 * Time.deltaTime;
}
the rotTracker is a GameObject variable. So, what is wrong with this code? The rotation tracker changes rotations but not the enemy. Maybe because it has child objects that look at a different thing? I created a sprite and put it on top of the enemy and it represents the enemies health and always turns towards the camera.

You can't change directly the angles. You need to change the vector positions. For example:
var yRotation -= 2 * Time.deltaTime;
transform.eulerAngles = new Vector3(0, yRotation, 0);
Hope this helps!

You shouldn't use transform.eulerAngles for increment, only fixed values. Also, better set it as vector, not the single axis.
If you've put the the script on the child and actually want to rotate the parent, then you have the wrong transform, but I can't clearly read that.
Further on I'd recommend doing something like this:
var dir = transform.postion - target.position;
dir.y = 0; // set the axis you want to rotate around to 0
var targetRotation = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, Time.deltaTime * speed);
speed being a factor for how fast you want to rotate.
(I think the code should be correct, I'm using C# though.)

Related

How do I make the hands follow the camera in my 3d FPS game?

So, basically I had the arms and head as a child of the camera but now I added some animations to my character and I have to use them in their initial position so the animation will work (I made the script for looking around and that is why I had them as a child of the camera). That means I have to find a different method for the hands to follow the camera. How should I approach this?
You should use this code. Basically what you want is to set a Vector3 to hand offset, and set a gameObject to the camera, and calculate from there:
Vector3 offset = new Vector3(0, 0, 0.3);
GameObject cam;
void Update(){
transform.position = cam.transform.position + offset;
}
Since your question wasn’t clear, and that might not have been what you wanted, you could use a parent game object, and set the camera as a child of it, and set the rest of the objects as child of that parent game object. Also make sure your player script should be in the parent game object.
Edit:
Make a parent game object, and name it “Player Rig”. Then out the camera underneath it in the hierarchy, and same for the hands. Place the hands where you want them to be. Then instead of having your scripts on the camera, put it on the Player Rig. Change the looking portion of your controller script to this:
void Update(){
float X = Input.GetAxis(“Mouse X) * rotSpeed * Time.deltaTime;
float Y = Input.GetAxis(“Mouse Y) * rotSpeed * Time.deltaTime;
Y = Mathf.Clamp(Y, -89.5f, 89.5f);
cam.transform.localRotation = Quaternion.Euler(Y, 0f, 0f);
arms.transform.localRotation = Quaternion.Euler(Y, 0f, 0f);
transform.rotation = Quaternion(0f, X, 0f);
}

Rotate Object around point and move it along sine function

First off: I am very new to Unity, as in VERY new.
I want to do the following: I want to rotate a cube around a stationary point (in my case a camera) with a radius that is adjustable in the inspector. The cube should always have its Z-axis oriented towards the camera's position. While the cube is orbiting around the camera, it should additionally follow a sine function to move up and down with a magnitude of 2.
I have some working code, the only problem is an increase in distance over time. The longer the runtime, the higher the distance between the cube and the camera.
Here is what I currently have:
void Awake()
{
cameraPosition = GameObject.FindGameObjectWithTag("MainCamera").transform;
transform.position = new Vector3(x: transform.position.x,
y: transform.position.y,
z: cameraPosition.position.z + radius);
movement = transform.position;
}
I instantiate some variables in the Awake()-method and set the cube's position to where it should be (do you instantiate in Awake()?). I'll use the Vector3 movement later in my code for the "swinging" of the cube.
void Update()
{
transform.LookAt(cameraPosition);
transform.RotateAround(cameraPosition.position, cameraPosition.transform.up, 30 * Time.deltaTime * rotationSpeed);
MoveAndRotate();
}
Here I set the orientation of the cube's z-axis and rotate it around the camera. 30 is just a constant i am using for tests.
void MoveAndRotate()
{
movement += transform.right * Time.deltaTime * movementSpeed;
transform.position = movement + Vector3.up * Mathf.Sin(Time.time * frequency) * magnitude;
}
To be quite frank, I do not understand this bit of code completely. I do however understand that this includes a rotation as it moves the cube along it's x-axis as well as along the world's y-axis. I have yet to get into Vector and matrices, so if you could share your knowledge on that topic as well I'd be grateful for that.
It seems like I have found the solution for my problem, and it is an easy one at that.
First of all we need the initial position of our cube because we need to have access to its original y-coordinate to account for offsets.
So in Awake(), instead of
movement = transform.position;
We simply change it to
initialPosition = transform.position;
To have more readable code.
Next, we change our MoveAndRotate()-method to only be a single line long.
void MoveAndRotate()
{
transform.position = new Vector3(transform.position.x,
Mathf.Sin(Time.time * frequency) * magnitude + initialPosition.y,
transform.position.z);
}
What exactly does that line then? It sets the position of our cube to a new Vector3. This Vector consists of
its current x-value
our newly calculated y-value (our height, if you want to say so) + the offset from our original position
its current z value
With this, the cube will only bop up and down with distancing itself from the camera.
I have also found the reason for the increase in distance: My method of movement does not describe a sphere (which would keep the distance the same no matter how you rotate the cube) but rather a plane. Of course, moving the cube along a plane will automatically increase the distance for some points of the movement.
For instantiating variables in Awake it should be fine, but you could also do it in the Start(){} Method that Unity provides if you wanted to.
For the main problem itself I'm guessing that calling this function every frame is the Problem, because you add on to the position.
movement += transform.right * Time.deltaTime * movementSpeed;
Would be nice if you could try to replace it with this code and see if it helped.
movement = transform.right * Time.deltaTime * movementSpeed;

1st person space ship pitch and yaw isue

I've been trying for some time now with different tutorials to get a nice firstperson (cockpit view) spaceship controll system. I tried using mouse only, keyboard only and combinations but I keep encountering the same problem with all tutorials. even this simple line of code does it:
transform.position += transform.forward * Time.deltaTime * 90f;
transform.Rotate( Input.GetAxis("Vertical"), Input.GetAxis("Horizontal"), 0.0f);
The problem I keep getting is that if I pitch its ok. it I yaw its ok. But If I do both (so I go diagonaly) it also rotates my ship on the Z axis and messes up my orientation. I tried locking the z rotation in the rigidbody but that does'nt help either. I tried making code myself alternating with apply torque and simply rotating, followed some tutorials including this one: Tutorial but keep getting the rotation problem.
What I want to make is a game that controlls like the old game Helbender
Does anyone of you know of a way that I can get spaceship controlls to work?
----EDIT-----
Got a bit further now. It doenst turn on my z axis anymore becouse I keep setting it to 0. Only problem now is that if I try to make a looping the ship flips around instead of nicely looping.
if (Input.GetKey("up"))
{
transform.Rotate(transform.right * -ShipPanSpeed * Time.deltaTime, Space.World);
}
if (Input.GetKey("down"))
{
transform.Rotate(transform.right * ShipPanSpeed * Time.deltaTime, Space.World);
}
if (Input.GetKey("left"))
{
transform.Rotate(transform.up * -ShipPanSpeed * Time.deltaTime,Space.World);
}
if (Input.GetKey("right"))
{
transform.Rotate(transform.up * ShipPanSpeed * Time.deltaTime,Space.World);
}
float z = transform.eulerAngles.z;
transform.Rotate(0, 0, -z);
You could always try to make one parent object for the Controls and then a child object (the spaceshit) that you can rotate for the pivot but not attach any movement beside rotation.
What i mean is that you can rotate the parent on the Y axis to make it rotate and move the transform forward or backward at the same time. If you want to pivot up or down you can transform forward at the sametime you transform up/down multiplied with the axis you want to pivot with
Example:
private void Update(){
//PARENT--------------------------------------------
// MOVING FORWARD AND BACKWARD
transform.position += transform.forward * Input.GetAxis("Vertical") * speed * Time.deltaTime();
// MOVING RIGHT AND LEFT
transform.position += transform.right * Input.GetAxis("Horizontal") * speed * Time.deltaTime();
//PIVOT UP AND DOWN
transform.position += transform.up * -Input.GetAxis("Mouse Y") * speed * Time.deltaTime();
//ROTATE AROUND THE Y AXIS
tranform.Rotate(0f, Input.GetAxis("Horizontal") * rotationspeed, 0f);
}
For the spaceship (child) for the pivot i would recommend you to make a emptyobject and set the chip to lookAt that object based on the input axis you use to move up/down and forward/backward.
Hope this helped or at least gave you a idea of how to make it :)

Unity2D: Rotate object keeping looking at front

I am trying to archive without success a z-axis rotation movement around a moving object keeping always "looking at front". So it should looks like this:
The closest I got was with:
transform.RotateAround(targetPosition, Vector3.forward, moveSpeed);
But it does not keeps looking "at front".
Could someone give me a hand with this?
Thank you in advance.
Best regards.
If your object ("Lightning Bolt") has no world rotation, i.e. aligned with the world axis as your example image seems to suggest, then the easiest is to simply set the world rotation to the Quaternion Identity:
transform.rotation = Quaternion.identity;
Note that the image wont rotate if its parent object rotates. It will essentially "Billboard" your lightning object. If you want to your lightning bolt to be aligned with a parent object, then try something like:
transform.rotation = transform.parent.rotation;
Fitst store the current rotation, then rotate around point, lastly apply the previous rotation.
var rot = transform.rotation;
transform.RotateAround(targetPosition, Vector3.forward, moveSpeed);
transform.rotation = rot;
A simple solution would just manipulate actual coordinates and ignore rotation ^^ If an object moves and you want it to keep rotating around it, just make it a child object.
This is a 3d solution where we rotate around Y:
void Start() { angle = 0.0f }
void Update() {
angle += speed * Time.deltaTime; //Your starting angle that will be modified every frame
CheckAngle(ref angle);
float x = Mathf.Cos(angle * Mathf.Deg2Rad) * Radius;
float z = Mathf.Sin(angle * Mathf.Deg2Rad) * Radius;
}
static void CheckAngle(ref float Angle) //It should probably return a value by it's name here tho not ref, not sure which is the correct way of doing this
{
if (Angle > 360) //You don't want your angle to go past the boundaries of an INT
Angle = 0;
}

How to Calculate Target Destination

I'm having a bit of trouble figuring this one out. What I'm trying to achieve is a sort of tackling motion. The player lunges at the target from a distance.
The diagram shows the set up. The blue diamond is the player and the red thing is the target. The purple box is the renderer bounds of the targets SkinnedMeshRenderer. I'm using renderer bounds because some target's mesh are much larger than other. Currently, the player is shooting to the orange star...which is unrealistic. I want him to, no matter what way the target is facing, always target the closest point of the target relative to his position...in the diagram's case that would be the brown star. Here's the code I've been using...
public IEnumerator Blitz()
{
rigidbody.velocity = Vector3.zero; //ZERO OUT THE RIGIDBODY VELOCITY TO GET READY FOR THE BLITZ
SkinnedMeshRenderer image = target.GetComponentInChildren<SkinnedMeshRenderer>();
Vector3 position = image.renderer.bounds.center + image.renderer.bounds.extents;
position.y = target.transform.position.y;
while(Vector3.Distance(transform.position, position) > 0.5f)
{
transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * 10);
yield return null;
}
Results(); //IRRELEVANT TO THIS PROBLEM. THIS CALCULATES DAMAGE.
Blitz.Stop(); //THE PARTICLE EFFECT ASSOCIATED WITH THE BLITZ.
GetComponent<Animator>().SetBool(moveName, false); //TRANSITIONS OUT OF THE BLITZ ANIMATION
GetComponent<Input>().NotAttacking(); //LET'S THE INPUT SCRIPT KNOW THE PLAYER CAN HAVE CONTROL BACK.
}
//Get the derection to tarvel in and normalize it to length of 1
Vector3 Direction = (Target - transform.position).normalized
With Direction, you can do many things. For example, you can multiply the direction by your speed and add that to your position.
transform.position += Direction * MoveSpeed;
If you want to get to the closest point, you can use the handy Collider.ClosestPointOnBounds method.
Target = TargetObject.GetComponent<Collider>().ClosestPointOnBounds(transform.position)
and plug the Target into the code used to get the direction.
Alternatively, you can use Vector3.Lerp without getting a direction since it's just interpolating.
transform.position = Vector3.Lerp(Target,transform.position,time.DeltaTime);
For stopping at the target point, you can use the arrival behavior.
//Declare the distance to start slowing down
float ClosingDistance = Speed * 2;
//Get the distance to the target
float Distance = (Target - transform.position).magnitude;
//Check if the player needs to slow down
if (Distance < ClosingDistance)
{
//If you're closer than the ClosingDistance, move slower
transform.position += Direction * (MoveSpeed * Distance / ClosingDistance);
}
else{
//If not, move at normal speed
transform.position += Directino * MoveSpeed;
}