unity3d boxcollider2d not colliding with Vector2.MoveTowards - c#

I am moving a sprite that has the following attached BoxCollider2D, Rigidbody2D (Dynamic set with simulated off) and a SpriteRenderer. Problem the trigger is not being set with the following code. I come from a 3D background and this would have triggered but its not in 2D not sure why, maybe things are different?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterController : MonoBehaviour
{
private MonsterInformation info;
private bool isMoving;
private Vector3 wantedPosition;
private Vector3 MaxPosition;
private Vector3 MinPosition;
private bool isAttacking;
// Start is called before the first frame update
void Start()
{
info = MonsterDatabase.Instance.MonsterLookup("Slime");
MaxPosition = new Vector3(transform.position.x + info.WanderingDistance,
transform.position.y + info.WanderingDistance, transform.position.z);
MinPosition = new Vector3(transform.position.x - info.WanderingDistance,
transform.position.y - info.WanderingDistance, transform.position.z);
}
public void Update()
{
if(!isMoving)
{
wantedPosition.x = Random.Range(MinPosition.x, MaxPosition.x);
wantedPosition.y = Random.Range(MinPosition.y, MaxPosition.y);
wantedPosition.z = transform.position.z;
isMoving = true;
}
if(isAttacking)
{
return;
}
transform.position = Vector2.MoveTowards(transform.position, wantedPosition,
Time.deltaTime * info.WalkingSpeed);
if(transform.position == wantedPosition)
{
isMoving = false;
}
}
public void OnTriggerEnter2D(Collider2D other)
{
Debug.Log($"Triggered {other.name}");
}
}
I am guessing that this needs to be moved through physics? transform.position = Vector2.MoveTowards(transform.position, wantedPosition,
Time.deltaTime * info.WalkingSpeed);
Also thank you for your time to respond to this question even if it seems like its stupid and I didn't do enough research, the main problem is Unity3D in a 3D environment I would collide with a box collider without having to move through physics so I am stumped as to why its not working in 2D.

Related

how can i convert a transform into a float

I am trying to take the current position of something once when collided and im not sure how to
do that could anyone help me out please?
The problem i have is that the script is grabbing the playerLocation constantly i need it so it grabs it once it collides.
basically when my object colides with something it moves towards a diferent object but i dont want it to follow it constantly i want it to get the position of that 1 object only once it has collided.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CircleMover : MonoBehaviour
{
public float speed = 10.0f;
public Transform playerLocation;
public float redirectSpeed;
public bool isCurrentlyColliding;
Vector3 playerposition;
private Rigidbody2D rb;
private Vector2 screenBounds;
// Start is called before the first frame update
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
rb.velocity = new Vector2(-speed, 0);
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
}
// Update is called once per frame
void Update()
{
//if (transform.position.x < -11.6f)
//{
// Destroy(this.gameObject);
//}
if (isCurrentlyColliding)
{
transform.position = Vector2.MoveTowards(transform.position, playerposition.transform.position, redirectSpeed * Time.deltaTime);
}
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("CopyCat"))
{
playerposition = (playerLocation.transform.position);
isCurrentlyColliding = true;
}
}
}
The reason it grabs the playerLocation constantly because you are using isCurrentlyColliding which you are never making false and also using it in Update() method which calls every frame.
You can do two things (choose whichever goes well with your code) :
by making isCurrentlyColliding false inside Update() method like this:
void Update()
{
if (isCurrentlyColliding)
{
transform.position = Vector2.MoveTowards(transform.position, playerposition.transform.position, redirectSpeed * Time.deltaTime);
isCurrentlyColliding = false;
}
}
by removing isCurrentlyColliding and setting transform.position directly inside OnTriggerEnter2D() method like this:
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("CopyCat"))
{
playerposition = (playerLocation.transform.position);
transform.position = Vector2.MoveTowards(transform.position, playerposition.transform.position, redirectSpeed * Time.deltaTime);
}
}

SetActive(True) not working after build but okay in the unity editor

I can't solve this problem where i want to hide and unhide a gameobject(UI) when i move using a VR controller. It came out fine in the editor but after build for the oculus quest(android), it stays inactive. anyone can help me? i put a list of UI that need to be hidden and wanted to set it active when the camera is not moving and hide when it is moving
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.UI;
public class ContinuousMovement : MonoBehaviour
{
//This script is used to make the VR Camera moves continuous using the analog
public float speed = 1;
public XRNode inputSource;
public float gravity = -9.81f;
public LayerMask groundLayer;
public float additionalHeight = 0.2f;
public List<GameObject> UiToBeHidden;
private float fallingSpeed;
private XRRig rig;
private Vector2 inputAxis;
private CharacterController character;
// Start is called before the first frame update
void Start()
{
character = GetComponent<CharacterController>();
rig = GetComponent<XRRig>();
foreach (GameObject ui in UiToBeHidden)
{
ui.SetActive(true);
}
}
// Update is called once per frame
void Update()
{
CapsuleFollowHeadset();
InputDevice device = InputDevices.GetDeviceAtXRNode(inputSource);
device.TryGetFeatureValue(CommonUsages.primary2DAxis, out inputAxis);
Quaternion headYaw = Quaternion.Euler(0, rig.cameraGameObject.transform.eulerAngles.y, 0);
Vector3 direction = headYaw * new Vector3(inputAxis.x, 0, inputAxis.y);
character.Move(direction * Time.fixedDeltaTime * speed);
if (inputAxis.x == 0 && inputAxis.y == 0)
{
Debug.Log("static");
foreach (GameObject ui in UiToBeHidden)
{
ui.SetActive(true);
}
}
else
{
Debug.Log("moving");
foreach (GameObject ui in UiToBeHidden)
{
ui.SetActive(false);
}
}
}
private void FixedUpdate()
{
//gravity
bool isGrounded = CheckIfGrounded();
if (isGrounded)
fallingSpeed = 0;
else
fallingSpeed += gravity * Time.fixedDeltaTime;
character.Move(Vector3.up * fallingSpeed * Time.fixedDeltaTime);
}
void CapsuleFollowHeadset()
{
character.height = rig.cameraInRigSpaceHeight + additionalHeight;
Vector3 capsuleCenter = transform.InverseTransformPoint(rig.cameraGameObject.transform.position);
character.center = new Vector3(capsuleCenter.x, character.height /2 + character.skinWidth, capsuleCenter.z);
}
bool CheckIfGrounded()
{
//tells us if on ground
Vector3 rayStart = transform.TransformPoint(character.center);
float rayLength = character.center.y + 0.01f;
bool hasHit = Physics.SphereCast(rayStart, character.radius, Vector3.down, out RaycastHit hitInfo, rayLength, groundLayer);
return hasHit;
}
}
I had exactly the same problem. The solution that works for me is changing the build setting.
Build Setting --> Player Settings --> Player --> Other Setting --> Api Compatibility level ( Change from .Net Standard 2.0 --> .Net 4.x)
That should work for you as well!

Unity jumping fails while going against a wall

Okay im trying to make my object (player) to jump everything is okay until i go against a wall and keep going against (still W is down) i cant jump wen im hitting a wall if i stop walking he will be enable to jump i tried making the walls on touch to make the player to have velocity = zero but it does not work,
i tried to add rigid body to the walls and freezing them in place, trying to make them kinematic does not work too .
I wish wen i go against walls and keep walking against them to be enable to jump.
If you know how i can do that please share thanks .
Here is the move script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour {
private float speed;
private float jumpHight;
private float straffeSpeed;
private float fallMultiplier;
private Rigidbody rig;
private Collider coll;
// Use this for initialization
private void Awake()
{
rig = GetComponent<Rigidbody>();
coll = GetComponent<Collider>();
straffeSpeed = 1.5f;
fallMultiplier = 2.5f;
speed = 10f;
jumpHight = 4f;
}
void Start () {
GroundCheck();
}
// Update is called once per frame
void Update () {
Move();
GroundCheck();
BetterFall();
}
private void Move()
{
float hAxis = Input.GetAxis("Horizontal") * straffeSpeed;
float vAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;
rig.MovePosition(transform.position + movement);
if (Input.GetKey(KeyCode.Space) && GroundCheck())
{
rig.velocity = Vector3.up * jumpHight;
}
}
private bool GroundCheck()
{
return Physics.Raycast(transform.position, -Vector3.up, coll.bounds.extents.y + 0.2f);
}
private void BetterFall()
{
if(rig.velocity.y < 0)
{
rig.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
}
}
if (Input.GetKeyDown(KeyCode.Space) && GroundCheck())
{
rig.velocity = Vector3.up * jumpHight;
}
I don't think you are doing this quite right. Try this:
if (Input.GetKeyDown(KeyCode.Space) && GroundCheck())
{
rig.AddForce(Vector3.up * jumpHight, ForceMode.Impulse);
}
:-)

Unity 5: Rigidbody 2d sticking to ceiling while velocity is moving upwards

I am making a 2d game. My problem is that while playing, if the player holds jump and is under a BoxCollider2D, the player will not fall until they release jump.
My player GameObject consists of a sprite renderer, a dynamic rigidbody2d with gravity on and a boxcollider2d.
Here are my movement scripts:
1:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class JumpScript : MonoBehaviour {
[Range(1, 10)]
public float jumpVelocity;
[Range(0,10)]
public float speed;
private bool jumpQueue = false;
private bool boolin=false;
void Update()
{
//Friggin fall, loser
//Jumping
///*
if (Input.GetButton("Jump")&& GetComponent<Rigidbody2D> ().velocity.y==0)
{
GetComponent<Rigidbody2D>().velocity = Vector2.up * jumpVelocity;
}
//*/
//jumpQueue?
/*
if(Input.GetButtonDown("Jump"))
{
jumpQueue = true;
}*/
//Right Movement
if (Input.GetKey(KeyCode.D))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(1*speed, GetComponent<Rigidbody2D>().velocity.y);
boolin = true;
}
if(Input.GetKeyUp(KeyCode.D))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
boolin = false;
}
//Left Movement
if (Input.GetKey(KeyCode.A))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(-1*speed, GetComponent<Rigidbody2D>().velocity.y);
boolin = true;
}
if (Input.GetKeyUp(KeyCode.A))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
boolin = false;
}
//No movement?
if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.A))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
boolin = false;
}
//Time to handle animation, boios.
Rigidbody2D rb = GetComponent<Rigidbody2D>();
bool schwomp = false;
bool schwift = false;
if(rb.velocity.y>0)
{
schwomp = true;
}
if(rb.velocity.y<0)
{
schwift = true;
}
Animator anim = GetComponent<Animator>();
if (boolin)
{
anim.SetInteger("Boolin", 1);
/*if (!anim.GetBool("expand"))
{
anim.SetBool("expand", true);
anim.Play("running");
}*/
}
else
{
anim.SetInteger("Boolin", 0);
/*
if(anim.GetBool("expand"))
{
anim.SetBool("expand", false);
anim.Play("Idle");
}*/
}
if(schwomp)
{
//anim.SetInteger("Boolin", 2);
}
if(schwift)
{
//anim.SetInteger("Boolin", 3);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BetterJumper : MonoBehaviour {
public float fallMultiplier = 2.5f;
public float lowJumpMultiplier = 2f;
Rigidbody2D rb;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if(rb.velocity.y<0)
{
rb.velocity += Vector2.up*Physics2D.gravity.y*(fallMultiplier-1)*Time.deltaTime;
}
else if(rb.velocity.y>0&&!Input.GetButton("Jump"))
{
rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
}
}
}
Thank you so much in advance!
You're using Input.GetKey() which will poll the key every frame. This means more and more velocity is added the longer you hold jump. You've effectively built a jetpack rather than a jump force.
You should use Input.GetKeyDown() which will only fire once when a key is pressed down, then has to be released and pressed again in order to re-trigger. You then need to apply a single sufficiently strong vertical force using RigidBody.AddForce() to make the character jump, rather than adding continuously to the velocity.
Additionally, you should really be caching the result of your GetComponent<Rigidbody2D>() call when the script either wakes up or starts so that you're not calling it continuously; Each one of those calls takes processing time. Also, you should be using FixedUpdate() for physics.
public class ExampleClass : MonoBehaviour {
public float thrust;
public Rigidbody rb; // make the rigidbody variable available anywhere in the class
void Start() {
// cache the rigidbody component to the variable once on start
rb = GetComponent<Rigidbody>();
}
void FixedUpdate() {
// use the variable reference from now on rather than making GetComponent calls
rb.AddForce(transform.up * thrust);
}
}
Soviut's answer explains it quite nicely, but there's more that you need to know. You're directly manipulating the velocity, which overrides the effect of any forces, including gravity(despite the fact you're applying it manually). See the documentation.
As demonstrated in Soviut's answer you should be applying forces and impulses, letting the physics engine determine the velocity. The only time you should set velocity directly is when you're building a simulation that intentionally has unrealistic physics(i.e. retro platformers). Even in that case, bear in mind that doing so creates a lot more work, because you'll need to factor in every little thing that creates movement. This means you're essentially re-inventing the physics engine.

Due to collision checking, my Unity character is occasionally falling through the floor. What can I do to fix this?

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.

Categories