• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by ClownChad · Jul 11, 2019 at 10:36 PM · movementrigidbody2dkinematicpixel artblurry

2D Pixel Art Player Blurry/Vibrates When Moving Via Kinematic Platformer Controller

Two example gifs here: https://imgur.com/a/st2ONuD

There are two sprites in the gifs. The above sprite is enlarged and is only moving back and forth. The smaller sprite is the player sprite and is controlled via a slightly modified 2D Kinematic Platformer Controller which I made following the Unity tutorial for making a kinematic platformer controller: https://www.youtube.com/watch?v=wGI2e3Dzk_w&list=PLX2vGYjWbI0SUWwVPCERK88Qw8hpjEGd8

Here are the scripts used for the player:

Physics Object Script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PhysicsObject : MonoBehaviour
 {
 
     [Header("Custom Physics Variables")]
     //0.65 is about a 50 degree angle on rotated object
     public float minGroundAngleY = 0.65f;
     public float gravityModifier = 1f;
     public Vector2 gravity = new Vector2(0, -9.8f);
 
     [Tooltip("Jump decay when going up")]
     public float jumpDecay = 0.2f;
     [Tooltip("Jump decay when player reaches apex and starts to fall")]
     public float jumpApexDecay = 0.3f;
 
     protected Vector2 targetVelocity;
     protected bool grounded;
     protected Vector2 groundNormal;
     protected Rigidbody2D rb;
     protected Vector2 velocity;
     protected ContactFilter2D contactFilter;
     protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
     protected List<RaycastHit2D> hitBufferList = new List<RaycastHit2D>(16);
 
     protected const float minCheckColDist = 0.001f;
     protected const float shellRadius = 0.01f;
 
     private void OnEnable()
     {
 
         rb = GetComponent<Rigidbody2D>();
 
     }
 
     private void Start()
     {
 
         contactFilter.useTriggers = false;
         contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
         contactFilter.useLayerMask = true;
 
     }
 
     private void Update()
     {
         targetVelocity = Vector2.zero;
         ComputeVelocity();
     }
 
     protected virtual void ComputeVelocity()
     {
 
     }
 
     private void FixedUpdate()
     {
         MovementPrep();
     }
 
     private void MovementPrep()
     {
         velocity += gravityModifier * gravity * Time.deltaTime;
         velocity.x = targetVelocity.x;
 
         if (velocity.y > 0)
         {
             velocity.y -= jumpDecay * Time.deltaTime;
         }
         else if (velocity.y < 0)
         {
             velocity.y -= jumpApexDecay * Time.deltaTime;
         }
 
         grounded = false;
 
         Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
 
         Vector2 move = moveAlongGround * velocity.x * Time.deltaTime;
 
         Movement(move, false);
 
         move = Vector2.up * velocity.y * Time.deltaTime;
 
         Movement(move, true);
     }
 
     private void Movement(Vector2 move, bool yMovement)
     {
 
         float colMoveDist = move.magnitude;
 
         if (colMoveDist > minCheckColDist)
         {
 
             int count = rb.Cast(move, contactFilter, hitBuffer, colMoveDist + shellRadius);
 
             hitBufferList.Clear();
 
             for (int i = 0; i < count; i++)
             {
                 hitBufferList.Add(hitBuffer[i]);
             }
 
             for (int i = 0; i < hitBufferList.Count; i++)
             {
                 Vector2 currentNormal = hitBufferList[i].normal;
 
                 if (currentNormal.y > minGroundAngleY)
                 {
                     grounded = true;
 
                     if (yMovement)
                     {
                         groundNormal = currentNormal;
                         currentNormal.x = 0;
                     }
                 }
 
                 float projection = Vector2.Dot(velocity, currentNormal);
 
                 if (projection < 0)
                 {
                     velocity = velocity - projection * currentNormal;
                 }
 
                 float modifiedDistance = hitBufferList[i].distance - shellRadius;
                 colMoveDist = modifiedDistance < colMoveDist ? modifiedDistance : colMoveDist;
             }
 
         }
 
         rb.position = rb.position + move.normalized * colMoveDist;
     }
 }

PlayerController Script

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerController : PhysicsObject
 {
     [Header("Player Variables")]
     public float speed = 7f;
     public float jumpPower = 10f;
 
     private SpriteRenderer spriteRender;
     private Animator animator;
 
     private void Awake()
     {
         spriteRender = transform.GetChild(0).GetComponent<SpriteRenderer>();
         animator = transform.GetChild(0).GetComponent<Animator>();
     }
 
     protected override void ComputeVelocity()
     {
         Vector2 move = Vector2.zero;
 
         if (!GameManager.instance.InShop)
         {
             move.x = Input.GetAxis("Horizontal");
 
             if (Input.GetButtonDown("Jump") && grounded)
             {
                 velocity.y = jumpPower;
             }
             else if (Input.GetButtonUp("Jump"))
             {
                 if (velocity.y > 0)
                     velocity.y *= 0.5f;
             }
         }
 
         targetVelocity = move * speed;
 
         if (Mathf.Abs(targetVelocity.x) > 0)
             animator.SetBool("moving", true);
         else
             animator.SetBool("moving", false);
 
         //If moving right
         if (move.x > 0)
         {
             if (!spriteRender.flipX)
                 spriteRender.flipX = true;
         }
         //If moving left
         else if (move.x < 0)
         {
             if (spriteRender.flipX)
                 spriteRender.flipX = false;
         }
     }
 }
 

And here is the test script I made for the larger sprite:

Test Script

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Test : MonoBehaviour
 {
     public float speed;
 
     private Rigidbody2D rb;
     private bool moveRight;
 
     private void Awake()
     {
         rb = GetComponent<Rigidbody2D>();
         moveRight = true;
     }
 
     private void FixedUpdate()
     {
         MoveRBObject();
     }
 
     private void MoveRBObject()
     {
         if (moveRight)
             rb.position = rb.position + (Vector2.right * speed * Time.deltaTime);
         else
             rb.position = rb.position + (Vector2.left * speed * Time.deltaTime);
 
         if (rb.position.x > 6)
             moveRight = false;
         else if (rb.position.x < -6)
             moveRight = true;
     }
 }
 

I've searched for a solution to fix the vibrating and have tried about a half a dozen different solutions but nothing seemed to have changed the vibrating in any significant way. A few things I have tried:

  • Changed rb.position to rb.MovePosition() and set the Rigidbody interpolation to "Interpolate" and "Extrapolate"

  • Made a very simple "pixel perfect" movement script which just changed the player sprite position on LateUpdate() to be to the nearest pixel position

  • Attempted having the movement code be in Update() as opposed to FixedUpdate()

  • Tried implementing the scripts from this post I found on movement in Unity: http://www.kinematicsoup.com/news/2016/8/9/rrypp5tkubynjwxhxjzd42s3o034o8 (Not sure if I implemented them correctly or not though. They didn't seem to change anything)

  • Updated my graphics card drivers

I would be very grateful for any tips or suggestions on how to fix this. Please let me know if you need more information to help solve the problem.

Thanks!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by MrRightclick · Jul 12, 2019 at 08:24 AM

With pixel art characters this small you might need to use a pixel perfect camera. Check out this Unity blog post about the new Pixel Perfect 2D asset: https://blogs.unity3d.com/2019/03/13/2d-pixel-perfect-how-to-set-up-your-unity-project-for-retro-8-bits-games/

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

167 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Move/Rotate Kinematic (2D) Child with MovePosition/MoveRotation Doesn't Work 0 Answers

2D Colliders stops working at random despite rigidbody, OnMouseDown not called 0 Answers

Kinematic rigidbody movement. 2 Answers

Make object jump to fixed y position 1 Answer

Stuttering/jerky movement of kinematic rigidbody 2d moving by velocity in 2D game on iOS 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges