I have a 2d platformer and there are these enemies with a patrol system as so:
public TextMeshProUGUI m_Object;
public SpriteRenderer sp;
public Transform groundCheck;
bool isFacingRight = true;
RaycastHit2D hit;
private void Update()
{
hit = Physics2D.Raycast(groundCheck.position, -transform.up, 1f, groundLayers);
}
private void FixedUpdate()
{
if(hit.collider != false)
{
if (isFacingRight)
{
rb.velocity = new Vector2(speed, rb.velocity.y);
}
else
{
rb.velocity = new Vector2(-speed, rb.velocity.y);
}
}
else
{
isFacingRight = !isFacingRight;
sp.transform.localScale = new Vector3(-transform.localScale.x, 1f, 1f);
Debug.Log(transform.localScale.x);
float placeholder = sp.transform.localScale.x;
m_Object.transform.localScale = new Vector3(placeholder, 1f, 1f);
Debug.Log(m_Object.transform.localScale.x);
}
}
In the end part I am trying to flip the text so it stays facing the logical way however it is not working since when it hits the edge the text disappears and when it its the other edge the text comes back.
Any Ideas would be appreciated.
Related
I want to code the car's rotation system as I move left and right. I use the following code for this.
float steer = Input.GetAxis("Horizontal");
float finalangel = steer * 45f;
wheelcoll[0].steerAngle = finalangel;
But I want to set it for the phone. When the user touches the screen of the phone and keeps his hand on the screen of the phone, the car goes to the left and stays. When the user removes his hand from the phone, the car returns to its original position. But when doing this process, I want the car to turn in the right direction.
How can I do this?
I tried this too:
[SerializeField] Rigidbody rb;
public Vector3 targetpostion;
public int Speed;
public bool FirstLaneBlueCar;
public bool BlueCar;
public Vector2 Xpos;
public float rotatlerptime;
bool rottrue;
void Start()
{
rottrue = false;
BlueCar = false;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}else if (Input.GetMouseButtonUp(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}
if (!rottrue)
{
if (transform.position.x <= 4f)
{
Debug.Log(">-.5");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
if (transform.position.x >= 3f)
{
Debug.Log(">.5f");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
}
}
private void FixedUpdate()
{
transform.Translate(targetpostion, Space.World);
if (BlueCar)
{
if (FirstLaneBlueCar)
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, -60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("left", .1f);
}
else
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("right", .1f);
}
}
}
public void rot2()
{
rottrue = false;
}
void left()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.y, transform.position.y, transform.position.z), .08f);
}
void right()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.x, transform.position.y, transform.position.z), .08f);
}
public void LeftButtonPressed()
{
if (FirstLaneBlueCar)
{
FirstLaneBlueCar = false;
}
else
{
FirstLaneBlueCar = true;
}
}
You can track the first touch position, and make the respective calculations in the Update method, comparing the previous touch position with the current one.
private void Update()
{
if (Input.touches.Length < 1)
return;
var touch = Input.touches[0];
var deltaPosition = touch.deltaPosition;
// Move the car according to the shift in touch position
}
You can also save the touch ID when the touch has just begun, so you can track the same touch later (user can have multiple fingers on the screen).
Use Touch.fingerId for that.
I'm new to Unity and I'm trying to make a drop attack for my character in 2D where if the attack button Z is pressed when the character is jumping, it'll swoop down as a diagonal line like a drop attack. My codes are below,
private Rigidbody2D rb;
private Animator anm;
private Collider2D coll;
private void Movement()
{
float hDir = Input.GetAxis("Horizontal");
if(!anm.GetCurrentAnimatorStateInfo(0).IsTag("attack"))
{
if (hDir < 0)
{
rb.velocity = new Vector2(-speedX, rb.velocity.y);
transform.localScale = new Vector2(-1, 1);
}
else if (hDir > 0)
{
rb.velocity = new Vector2(speedX, rb.velocity.y);
transform.localScale = new Vector2(1, 1);
}
}
else if(anm.GetCurrentAnimatorStateInfo(0).IsTag("attack"))
{
rb.velocity = new Vector2(0, 0);
}
if (Input.GetButtonDown("Jump") && coll.IsTouchingLayers(ground))
{
Jump();
}
}
private void Attack() {
anm.SetTrigger("attack");
if (!coll.IsTouchingLayers(ground)) {
rb.velocity = new Vector2(speedX * Time.deltaTime, rb.velocity.y);
}
}
private void Jump() {
rb.velocity = new Vector2(rb.velocity.x, jumpforce);
state = State.jumping;
}
I think it has something to do at the Attack() function.
I started doing some simple stuff in Unity (goal is to make a great game) so I made a simple Player Controller.
public class PlayerController : MonoBehaviour
{
public float walkingSpeed;
public float jumpSpeed;
public bool jumpFlag = false;
public float maxJumpDistance = 1.0f;
Rigidbody rb;
Collider col;
Vector3 playerSize;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
playerSize = col.bounds.size;
}
// Update is called once per frame
void FixedUpdate()
{
WalkHandler();
JumpHandler();
}
void WalkHandler()
{
float horizonstalAxis = Input.GetAxis("Horizontal");
float verticalAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(-horizonstalAxis * walkingSpeed * Time.deltaTime, 0, -verticalAxis * walkingSpeed * Time.deltaTime);
rb.MovePosition(transform.position += movement);
}
void JumpHandler()
{
float jumpAxis = Input.GetAxis("Jump");
//Debug.Log(jumpAxis);
if (jumpAxis > 0)
{
bool isGrounded = CheckGrounded();
if (jumpFlag != true && isGrounded)
{
jumpFlag = true;
Vector3 jumpVector = new Vector3(0, jumpSpeed * Time.deltaTime, 0);
rb.AddForce(jumpVector, ForceMode.VelocityChange);
}
}
else
{
jumpFlag = false;
}
}
bool CheckGrounded()
{
Vector3 checkerPoint = transform.position + new Vector3(0, -playerSize.y / 2, 0);
bool grounded = Physics.Raycast(checkerPoint, -Vector3.up, maxJumpDistance);
return grounded;
}
I came across a wierd problem. In some parts of the scene my method JumpHandler is not working. After reaching some z coordinates, the CheckGrounded returns False instead of True, even though the Raycast direction is set down.
Can anyone help?
Here is my code:
public class CharacterController : MonoBehaviour
{
private Vector3 _startLocation = Vector3.zero;
private Vector3 _currentLocation = Vector3.zero;
private Vector3 _endLocation = Vector3.zero;
private bool _isMoving = false;
private float _distanceToTravel;
private float _startTime;
public float Speed = 1.0f;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Left mouse button clicked");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject.CompareTag("Ground"))
{
_startLocation = transform.position;
_endLocation = hit.point;
_isMoving = true;
_startTime = Time.time;
_distanceToTravel = Vector3.Distance(_startLocation, _endLocation);
Debug.Log(string.Format("Ground has been hit: Start: {0}, End: {1}", _startLocation.ToString(), _endLocation.ToString()));
}
}
}
if (_isMoving)
Move();
}
void Move()
{
float timeElapsed = (Time.time - _startTime) * Speed;
float t = timeElapsed / _distanceToTravel;
_currentLocation = Vector3.Lerp(_startLocation, _endLocation, t);
transform.Translate(_currentLocation);
if (_currentLocation == _endLocation)
{
Debug.Log(string.Format("Destination reached ({0})", _endLocation.ToString()));
_isMoving = false;
}
}
}
I read the documentation on the Vector3.Lerp function, as well as the Physics.Raycast function, and ended up with this code.
The debug console confirms that the Ground has been hit, but my capsule starts moving upwards in the Y direction and never stops!
I'm still very new to Unity and game development in general, so I'm still learning, but any pointers on what I'm doing wrong?
it is moving in the Y because you use transform.Translate.
transform.Translate is moving it, so if you did transform.Translate(0, 0, 10)
it would move in the z, and if you did transform.Translate(0, 10, 10)
it will move in the y and z direction.
So to fix this i will show you 2 ways:
1) Using Vector3.Lerp:
transform.position = Vector3.Lerp(_startLocation, _endLocation, t);
2) Using MoveTowards:
transform.position = Vector3.MoveTowards(transform.position, _endLocation, Speed * Time.deltaTime);
In the first Vector3.Lerp is used, and i see you use it too
_currentLocation = Vector3.Lerp(_startLocation, _endLocation, t);
So you could do either this:
transform.position = Vector3.Lerp(_startLocation, _endLocation, t);
or this
transform.position = _currentLocation;
Both will do the same because you assigned _currentLocation to
Vector3.Lerp(_startLocation, _endLocation, t);
And you can read about MoveTowards here
http://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html
Check the Comments line You will understand what I had edited to bring the Solution.
It works well for me
void Start()
{
_startLocation = transform.position; // Changed Here to Initialize once
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Left mouse button clicked");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.gameObject.CompareTag("Ground"))
{
print(hit.point);
//**Here you mentioned _StartLocation = transform.position
//this instantly changes the starting point Every time so
//if SP changes then totally changed in Translation.***
_endLocation= hit.point;
_isMoving = true;
_startTime = Time.time;
_distanceToTravel = Vector3.Distance(_startLocation, _endLocation);
}
}
}
if (_isMoving)
{
Move();
}
}
void Move()
{
float timeElapsed = (Time.time - _startTime) * Speed;
float t = timeElapsed / _distanceToTravel;
_currentLocation = Vector3.Lerp(_startLocation, _endLocation, t);
transform.position = Vector3.Lerp(_startLocation, _endLocation, t);
_startLocation = _endLocation;
//*** This line is for Next Mouse
//click. So every next click StartPoint is Current Click
//EndPoint***
if (_currentLocation == _endLocation)
{
Debug.Log(string.Format("Destination reached ({0})", _endLocation.ToString()));
_isMoving = false;
}
}
}
I have a basic 2D-oriented Character Controller - custom, that I'm writing for a 2.5D game with 3D models (Therefore I can't use the Unity2D physics and collision volumes).
My controller mostly works, however I'm hitting a strange little issue where every so often - apparently at a certain speed - it skips the collision check and falls through the floor or platform. Can someone spot what I'm doing wrong?
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float PlayerSpeed;
public float JumpPower;
public float _Gravity = 9.89f;
public Vector3 Flip = Vector3.zero;
private Vector3 MoveDirection = Vector3.zero;
private bool FacingLeft = false;
private bool FacingRear = false;
public bool GroundContact = false;
private Rigidbody RigidBody;
private void Awake()
{
RigidBody = GetComponent<Rigidbody>();
}
private void Update()
{
DetectionRays();
MoveDirection.x = PlayerSpeed * Input.GetAxis("Horizontal");
if (GroundContact) {
MoveDirection.y = 0;
if (Input.GetButtonDown("Jump")) {
MoveDirection.y = JumpPower;
}
} else {
MoveDirection.y -= _Gravity * Time.deltaTime;
}
Vector3 movementVector = new Vector3(MoveDirection.x * Time.deltaTime, MoveDirection.y * Time.deltaTime, 0);
transform.Translate(movementVector);
}
private void DetectionRays()
{
DetectDown();
}
private void OnCollisionEnter(Collision Collide)
{
if (Collide.transform.tag == "Ground")
{
GroundContact = true;
}
}
private void DetectDown()
{
RaycastHit Obsticle;
Vector3 RayDownPosit = transform.position;
RayDownPosit.y += 0.8f;
Ray RayDown = new Ray(transform.position, Vector3.down);
Debug.DrawRay(RayDownPosit, Vector3.down, Color.red, 0.05f, false);
GroundContact = false;
if (Physics.Raycast(RayDown, out Obsticle, 0.05f))
{
if (Obsticle.transform.tag == "Ground")
{
GroundContact = true;
}
}
}
}
First, you can attach Box Collider 2D and Rigidbody 2D to 3D models. Try it.
Are you sure you need a custom character controller? CharacterController.Move (or SimpleMove) does collision detection for you.
http://docs.unity3d.com/ScriptReference/CharacterController.Move.html
Alternatively, since you are using Rigidbodies, you should consider using ApplyForce or adding velocity.