c# - 2D Object Collison Unity -
i'm developing simple 2d game in unity, , have run problem when dealing collision. have 2 objects, tree , player. tree doesn't move, , represented sprites , polygon collider. player moves using custom script (not character controller), , has kinematic ridgidbody , polygon collider attached.
my intended behavior player 'collide' tree , blocked it, none of objects able move. however, doesn't seem simple way of doing this.
setting tree's ridgidbody component 'static' or 'dynamic' results in no collision being detected. considered making player 'dynamic' rigid body, unity docs suggest dynamic rigidbodies should not moved transform component, how current system works. additionally, setting dynamic results in unintended behavior player freezes no reason, , since no physics applied on player object, seems bad use case dynamic. wrong though.
i possibly use script somehow lock player position when collider event triggered, seems hacky. can provide insight on how handle this?
well apparently 2d colissions little bit buggy. here approach avoid issues. instead of relying on colliders, uses raycast check if there obstacle player attempting move
using unityengine; using system.collections; using unityengine.ui; public class player : movingobjects { protected override void attemptmove<t> (int xdir, int ydir) { base.attemptmove<t> (xdir, ydir); raycasthit2d hit; } protected override void oncantmove<t>(t component) { wall hitwall = component wall; hitwall.damagewall (walldamage); } // update called once per frame void update () { int horizontal = 0; int vertical = 0; horizontal = (int)input.getaxisraw ("horizontal"); vertical = (int)input.getaxisraw ("vertical"); if (horizontal != 0) vertical = 0; if (horizontal != 0 || vertical != 0) attemptmove<wall> (horizontal, vertical); } }
which inherits from:
using unityengine; using system.collections; public abstract class movingobjects : monobehaviour { public float movetime = 0.1f; public layermask blockinglayer; private boxcollider2d boxcollider; private rigidbody2d rb2d; private float inversemovetime; protected virtual void start() { boxcollider = getcomponent<boxcollider2d> (); rb2d = getcomponent <rigidbody2d>(); inversemovetime = 1f / movetime; } protected ienumerator smoothmovement(vector3 end) { float sqrremainindistance = (transform.position - end).sqrmagnitude; while (sqrremainindistance > float.epsilon) { vector3 newposition = vector3.movetowards(rb2d.position, end, inversemovetime*time.deltatime); rb2d.moveposition(newposition); sqrremainindistance = (transform.position - end).sqrmagnitude; yield return null; } } protected bool move(int xdir, int ydir, out raycasthit2d hit) { vector2 start = transform.position; vector2 end = start + new vector2 (xdir, ydir); boxcollider.enabled = false; hit = physics2d.linecast (start, end, blockinglayer); boxcollider.enabled = true; if (hit.transform == null) { startcoroutine(smoothmovement(end)); return true; } return false; } protected virtual void attemptmove<t>(int xdir, int ydir) t : component { raycasthit2d hit; bool canmove = move (xdir, ydir, out hit); if (hit.transform == null) return; debug.log ("something hit", gameobject); t hitcomponent = hit.transform.getcomponent<t> (); if (!canmove && hitcomponent != null) oncantmove (hitcomponent); } protected abstract void oncantmove<t>(t component) t: component; }
this script belongs tutorial of oficial unity website. 2d game called rogue. here link in case planning similar:
https://unity3d.com/es/learn/tutorials/projects/2d-roguelike-tutorial
Comments
Post a Comment