Collision with object on another layer isn't working in Unity? - unity3d

I have two box colliders in my scene. I am basically manipulating one and the other is stationary and just on the default layer and it also has a rigidbody attached. The other object I am mostly rotating and for some reason it rotates right through the other object. It is on another layer but, I have checked the layer collision matrix and all of the boxes are checked so I'm not sure why the collision isn't happening. Is there a reason for this?
I am Rotating it with transform.Rotate. Neither of the colliders have the isTrigger selected. Any thoughts?
EDIT: Added this to show implementation of rigidbody.MoveRotation
private void FixedUpdate()
{
if (Input.GetKey(KeyCode.Y) && !colliding)
{
if (rigidBody == null)
{
rigidBody = gameObject.AddComponent<Rigidbody>();
rigidBody.isKinematic = true;
rigidBody.useGravity = false;
rigidBody.interpolation = RigidbodyInterpolation.Interpolate;
}
rot = Quaternion.Euler(0, .5f, 0);
rigidBody.MoveRotation(rigidBody.rotation * rot );
}
if (Input.GetKey(KeyCode.I) && !colliding)
{
if (rigidBody == null)
{
rigidBody = gameObject.AddComponent<Rigidbody>();
rigidBody.isKinematic = true;
rigidBody.useGravity = false;
rigidBody.interpolation = RigidbodyInterpolation.Interpolate;
}
rot = Quaternion.Euler(0, -.5f, 0);
rigidBody.MoveRotation(rigidBody.rotation * rot);
}
else if (colliding)
{
rigidBody.MoveRotation(rigidBody.rotation * Quaternion.Inverse(rot));
}
}

Collisions do not happen if you update the position or rotation of any object through the transform. You can receive the OnCollision events but you will not get the desire results if you rotate or move using the transform. Update your code to use the rigidbody for any changes to rotation and position in a fixedUpdate to receive these effects, aka colliding.

Related

Unity 2D. Why raycasting does not work properly?

With this code I am changing color of gun object if raycast can hit player. Color changes as soon as Player walks into raycast radius. However color won't switch back from red to green as soon as player either goes away (more than Range distance) or hide behind walls. It will eventually switch back to green but not right away. Can you please help me figure out what seems to be the problem?
void Update()
{
Vector2 targetPos = Target.position;
Direction = targetPos - (Vector2)transform.position;
RaycastHit2D rayInfo = Physics2D.Raycast(transform.position, Direction, Range, layerMask);
if (rayInfo)
{
if (rayInfo.collider.gameObject.tag == "Player")
{
if (Detected == false)
{
Detected = true;
Gun.GetComponent<SpriteRenderer>().color = Color.red;
}
}
else
{
if (Detected == true)
{
Detected = false;
Gun.GetComponent<SpriteRenderer>().color = Color.green;
}
}
}
}
When your raycasthit doesn't hit anything with specified LayerMask you don't change your gun's color maybe this is the issue. if your reset your gun color it can solve. Here is the example
//define gunColor variable it is default color of your gun
Color gunColor=Color.green;
void Update()
{
Vector2 targetPos = Target.position;
Direction = targetPos - (Vector2)transform.position;
RaycastHit2D rayInfo = Physics2D.Raycast(transform.position, Direction, Range, layerMask);
if (rayInfo)
{
gunColor=rayInfo.collider.gameObject.CompareTag("Player")?Color.red:Color.green,
}else{
//when raycasthit doesnt hit any thing set gun color to green;
gunColor=Color.green;
}
//update gun color
Gun.GetComponent<SpriteRenderer>().color = gunColor;
}

Move GameObject with Sprite Renderer animation

I have an object in which I have added a sprite Render and an animation to see a sprite sheet in motion, the fact is that I want this object to move from one position to another. But I don't understand why it doesn't work.
The first thing I do with this object is to instantiate it to make a clone.
Then in the update I do the following:
Method void:
spriteRenderer = throwObject.spriteRenderer;
GameObject spriteRendererObject = Instantiate(spriteRenderer);
Update:
if(_animationStarted2){
Vector3 startPos = transform.position;
Vector3 targetPos = _targetPos;
spriteRenderer.transform.position = Vector3.MoveTowards(startPos, Vector3.Lerp(startPos, targetPos, 0.1f),speed);
if (startPos == targetPos)
{
_animationStarted2 = false;
Destroy(gameObject, 0.25f);
}
}

Jump functionality for a 2D Top Down Unity game?

I am struggling to find an efficient way to let my player jump in a 2D Top Down world. I can see a lot of tutorials about platformer views where the camera is oriented at the side of the player, but nothing really working for a top down view like startdew Valley.
I am not using physics, so I move the character on the tilemap using a Couroutine which moves the player to the next position on grid, here it is my Update and DoMove methods:
private void Update()
{
if (!isMoving)
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
if (input.x != 0)
input.y = 0;
if (input != Vector2.zero)
{
animator.SetFloat("Horizontal", input.x);
animator.SetFloat("Vertical", input.y);
var targetPos = transform.position + new Vector3(input.x, input.y, 0f);
// obstacle detection
Vector3Int obstaclesMapTile = obstacles.WorldToCell(targetPos - new Vector3(0, .5f, 0));
if (obstacles.GetTile(obstaclesMapTile) == null)
{
StartCoroutine(DoMove(targetPos));
}
}
animator.SetFloat("Speed", input.sqrMagnitude);
}
}
private IEnumerator DoMove(Vector3 newPos)
{
isMoving = true;
while ((newPos - transform.position).sqrMagnitude > Mathf.Epsilon)
{
transform.position = Vector3.MoveTowards(transform.position, newPos, moveSpeed * Time.fixedDeltaTime);
yield return null;
}
transform.position = newPos;
isMoving = false;
}
Is there anybody which could give me an hint on how to add a jumping feature? ( ideally with animation support?) I am kind of running out of ideas.
Thanks in advance.
Just think of it as animation only. Since it is 2D top down, it's more about it looking like it jumps, and then if it has to go over something while in the jump animation, test for just that.
For example; if over hole and jump animation is playing, then allow movement over the whole, otherwise fall. So if the player presses the button for jump, the animation would play, and there should be some variable storing what animation the player is currently in.

Unity2D object rotation on Mobile device

I want to know if there is a way to rotate the object only when the user click and drag on the gameobject. If the user click and drag anywhere else, the gameobject should not rotate.
Object with this script on it is rotating no matter where the user clicks.
void Update()
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Moved)
{
Vector2 dir = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position) - Camera.main.ScreenToWorldPoint(transform.position);
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle - 90, Vector3.forward);
transform.rotation = rotation;
transform.rotation = rotationZ * transform.rotation;
}
}
Your current code indeed only checks for touches .. it doesn't matter whether these are "hitting" anything or not.
You could e.g. use a Physics.Raycast in order to check if your touch is above an object using
// store the direction from object to touch when the touch started
private Vector2 startDirection;
// store the objects orientation when the touch started
private Quaternion startRotation;
// only process touch moved if the touch actually started above this object
private bool isValidTouch;
// The collider of this object
[SerializeField] Collider _collider;
// The main camera
[SerializeField] Camera _mainCamera;
private void Awake()
{
if(!_collider) _collider = GetComponent<Collider>();
if(!_mainCamera) _mainCamera = Camera.main;
}
void Update()
{
if (Input.touchCount > 0)
{
touch = Input.GetTouch(0);
var touchPosition = touch.position;
switch(touch.phase)
{
case TouchPhase.Began:
// Check if this touch actually is over this object
if(_collider.RayCast(_mainCamera.ScreenPointToRay(touchPosition), out var hit))
{
// Now store initial data
// You want to do ONLY ONE:
// - Either transform the touch into worldspace (more complicated)
// - OR transform the position into screenspace (easier)
// You definitely do not want to do both!
startDirection = (touchPosition - (Vector2)_mainCamera.WorldToScreenPoint(transform.position));
startRotation = transform.rotation;
isValidTouch = true;
}
break;
case TouchPhase.Moved
if(isValidTouch)
{
// Get the current touch direction
var direction = (touchPosition - (Vector2)_mainCamera.WorldToScreenPoint(transform.position));
// Get the angle between them
var differenceAngle = Vector3.SignedAngle(startDirection, direction, Vector3.forward);
// rotate the original rotation according to the current angle
Quaternion rotation = startRotation * Quaternion.AngleAxis(differenceAngle, Vector3.forward);
transform.rotation = rotation;
}
break;
case TouchPhase.Ended
isValidTouch = false;
break;
}
}
}

Unity changing friction from code not working (2D)

I want to change a collider's physic's material from code, I use the code below. I see the material's friction changing in the inspector, however the collider behaves as if the friction wouldn't change.
void checkOnGround() {
Transform t;
foreach(Collider2D c in collidingTiles) {
t = c.transform;
if(t.position.y - transform.position.y < -Misc.TILE_SIZE * 0.75f) {
onGround = true;
myCollider.sharedMaterial.friction = 0.8f;
return;
}
}
onGround = false;
myCollider.sharedMaterial.friction = 0f;
return;
}
There are knowed Unity bug.
You can disable/enable your collider to got the material changed applied, and a little flick texture sometimes.