I am currently working on the Flooded Grounds Unity Asset, I'm implementing an Alien NPC, with a script that tells it to follow the player.
The problem that I'm encountering is that the Alien turns his back to the player and I can't figure out why. I also tried rotating it by 180° on the Y axis (both in the transform and inside of the script using transform.rotate.y - when using the transform doesn't make any difference while using it in the update function just makes it constantly snap back and forth).
Here's a video of the issue:
https://drive.google.com/file/d/1tC9zJWKXXDuNZNZJbl2htBUgTPSTB4IG/view?usp=sharing
And here's the script that I'm using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyFollow : MonoBehaviour
{
public NavMeshAgent enemy;
public Transform Player;
private Rigidbody alienRb;
private Animator alienAnim;
// Start is called before the first frame update
void Start()
{
alienRb = GetComponent<Rigidbody>();
alienAnim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
enemy.SetDestination(Player.position);
if(enemy.velocity.magnitude > 0)
{
alienAnim.SetTrigger("Walk");
}
}
}
Any help would be very appreciated!
Hello Mazza ^^ First of all, I have to say that your alien monster is really cute :D Anyway, did you try transform.LookAt(Player.transform.position)? Also, transform.rotation is might not be affective, maybe you can try alien.transform.Rotate(0.0f, 90.0f, 0.0f, Space.Self); or transform.rotation = Quaternion.Euler(transform.rotation.x, transform.rotation.y - 180f, transform.rotation.z)
Related
so I have rigid body and when it collides with another body with low speeds it is working just fine but when it collides with hight speed it goes through the object I've Been have this problem for day and I can't fix it
here's my code
this is my player movement file
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharcterController : MonoBehaviour
{
// Start is called before the first frame update
public Vector3 PlayerMovementVar;
public Rigidbody Rigidbody_comp;
// Start is called before the first frame update
void Start()
{
Rigidbody_comp = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
PlayerMovement();
}
void PlayerMovement()
{
float horizontalAxis = Input.GetAxis("Horizontal")/30;
float verticalAxis = Input.GetAxis("Vertical")/30;
PlayerMovementVar = new Vector3(horizontalAxis,0f,verticalAxis);
transform.Translate(PlayerMovementVar,Space.Self);
}
}
I shouldn't be the one answering this since I have very little knowledge of unity but I'm pretty sure it might be because you are using transform.Translate which I think it avoids collisions try using a character controller instead :)
If you want to use properly Unity physics system you must use Forces instead of Translate direcly your gameobject.
Try this:
Rigidbody_comp.AddForce(PlayerMovementVar);
instead of
transform.Translate(PlayerMovementVar,Space.Self);
RigidBody movement and Transform movement are different from each other, each causes a different type of movement. when moving with a rigidbody, in order to use its physics ability, you should move it instead of the usual transform.Translate.
Rigidbody_comp.AddForce(PlayerMovementVar);
I was attempting to make a top down 2D shooter using Unity. My code contains no errors that I could see, RigidBody2D and PlayerMovement (code for the player to move) have been added to the sprite, and RigidBody2D has been added to the PlayerMovement. My move speed is set to 5. Please let me know what I can do to fix this issue!
Code:
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed;
public Rigidbody2D rb;
Vector2 movement;
void Update()
{
MovementInput();
}
private void FixedUpdate()
{
rb.velocity = movement * moveSpeed;
}
void MovementInput()
{
float mx = Input.GetAxisRaw("Horizontal");
float my = Input.GetAxisRaw("Vertical");
movement = new Vector2(mx, my).normalized;
}
}
Use your character sprite as the mouse cursor instead to write a code to make the player follow the mouse pos
If you really want to move your player via script this video will help you https://www.youtube.com/watch?v=0Qy3l3VuF_o
Have a good day :)
Check if your rigidbody2D's Body type is set to static, If it is then set it to kinematic or dynamic.
Also where did you import the script to?
Your code is not the problem, I tested it myself! Although you could move MovementInput(); to the FixedUpdate. Its not required though.
Edit: Image of the inspector as i have it if it helps
this is my first question on StackOverflow, please pardon and fix me if I ask something inappropriate.
I was creating a basic animated scene, where my GameObjects (Which are a couple of pre-animated animals) are running throughout the scene.
Here is the script:
using UnityEngine;
using System.Collections;
public class Locomotion : MonoBehaviour
{
void Update()
{
transform.Translate(Vector3.forward * Time.deltaTime);
}
}
Now my question is, how can I make them turn 180 degrees around when they hit a collider? Any modification to my existing code is welcomed
I mostly agree with the fine gentleman in that you should use a Rigidbody component to move your animals.
Something like this:
using UnityEngine;
using System.Collections;
public class Locomotion : MonoBehaviour
{
public RigidBody rb;
void FixedUpdate()
{
rb.velocity=Vector3.forward;
//or you could use rb.AddForce(Vector3.forward)
//but in simple cases such as this one it's not necessary
}
}
Be sure to call all physics calculations from FixedUpdate and not Update, because it you don't your objects can "jitter" in the scene (not going into detail on that).
About the collision detection and the 180:
To detect collisions you have to have a RigidBody component on your objects, as well as a Collider on your objects, as well as on the walls you want to collide with.
The way you check for collisions:
using UnityEngine;
public class Test : MonoBehaviour
{
public Rigidbody rb;
void FixedUpdate()
{
//this is the part that moves your animals,
//i use transform.forward instead of Vector3.forward because this way
//it will point in the forward direction of the animal, even if i rotate it
rb.velocity = transform.forward;
}
private void OnCollisionEnter(Collision collision)
{
//i tagged the walls i want to turn back the animals as "wall" in the unity editor
//and here i check if the thing i collided with is a wall
if (collision.gameObject.CompareTag("wall"))
{
//this line basicly says: look in the direction that is currently behind you
transform.rotation = Quaternion.LookRotation(transform.forward * -1);
}
}
}
Goal: Syncronize player position in a multiplayer game in Unity that uses the Mirror Networking API
Problem:
Using the NetworkTransform component the position seems to not be precisely syncronized, both the client and the server sees the player in the wrong position, players tend to fly with no reason
I tried making a separated script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class PlayerSyncronization : NetworkBehaviour
{
[SyncVar]
public Vector3 syncPosition;
[SyncVar]
public Quaternion syncRotation;
public float lerpRate = 15;
private void FixedUpdate()
{
TransmitPosition();
Lerp();
}
void Lerp()
{
if (!hasAuthority) return;
transform.position = Vector3.Lerp(transform.position, syncPosition, Time.deltaTime * lerpRate);
transform.rotation = Quaternion.Lerp(transform.rotation, syncRotation, Time.deltaTime * lerpRate);
}
[ClientCallback]
void TransmitPosition()
{
CmdProvidePositionToServer(transform.position, transform.rotation);
}
[Command]
void CmdProvidePositionToServer(Vector3 pos, Quaternion rot)
{
syncPosition = pos;
syncRotation = rot;
}
}
but the result is the same of the network transform component, and even if a player stops walking, on the other side he keeps walking till he falls off the map
Those are the errors/warning i got using the script
Info:
Player movement is client side as I'm using root motion.
I can't use IsLocalPlayer as it works only if the player is directly spawned by the NetworkManger and my players are being spawned by a separated script.
Right now, even if I'm not using it, i have a CharacterController in my PlayerPrefab
I'm using Steamworks to make the players connect through internet
If more info are needed just tell me.
I understood that the problem was the Character controller I was using, so in the player script I checked if the player had authority, if not I destroyed the character controller, and if i was destroying it on the server I replaced it with a normal collider without physics, so i could still have collisions
This is a reduced version of the player controller I am using now, which still produces the error explained below:
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private float m_RunSpeed;
private CharacterController m_CharacterController;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
}
private void FixedUpdate()
{
Vector3 move = Vector3.right * m_RunSpeed;
m_CharacterController.Move(move * Time.fixedDeltaTime);
}
}
}
I am using the standard assets script and I am trying to have a script teleport the player to different places. When I try and move the player it goes to that position for a frame, then goes right back to its position.
player.transform = new Vector3(1,2,3);
// works as expected, but then next frame, player's
// position is back to where it was before
This problem occurs because Move may not be able to read the up-to-date values for transform.position.
This problem has been reported on the official Unity Issue Tracker here, and a solution was posted there as well:
The problem here is that auto sync transforms is disabled in the physics settings, so characterController.Move() won't necessarily be aware of the new pose as set by the transform unless a FixedUpdate or Physics.Simulate() called happened in-between transform.position and CC.Move().
To fix that, either enable auto sync transforms in the physics settings, or sync manually via Physics.SyncTransforms right before calling Move()
So, you could fix your problem by editing FixedUpdate so that it calls Physics.SyncTransforms before Move, like this:
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private float m_RunSpeed;
private CharacterController m_CharacterController;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
}
private void FixedUpdate()
{
Vector3 move = Vector3.right * m_RunSpeed;
Physics.SyncTransforms();
m_CharacterController.Move(move * Time.fixedDeltaTime);
}
}
}