Charactercontroller skin width accurate
I have try to build a 3d sokoban model, I use charactercontroller as for my player prefab with a blocky move(one keypressdown per move at a block distance). When my player touch the wall the actual position is adjust to a (0.99, 0 , 1.01) with a skin width at 0.01. I want the player perfectly touch the wall when a wall ahead and also stand in the center of a floor block instead of keep a 0.01 distance away from the wall. Here is the code I written down for player.
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
private int counter;
private CharacterController controller;
private string tmp;
// Use this for initialization
void Start () {
this.controller = GetComponent<CharacterController>();
this.counter = -1;
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.UpArrow))
{
MoveUp();
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
MoveDown();
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
MoveLeft();
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
MoveRight();
}
}
//Control player to move up
void MoveUp()
{
controller.Move(Vector3.forward);
}
//Control player to move down
void MoveDown()
{
controller.Move(Vector3.back);
}
//Control player to move left
void MoveLeft()
{
controller.Move(Vector3.left);
}
//control player to move right
void MoveRight()
{
controller.Move(Vector3.right);
}
public void OnControllerColliderHit(ControllerColliderHit hit)
{
if(hit.gameObject.tag == "Crate")
{
Crate crate = hit.gameObject.GetComponent<Crate>();
Vector3 direction;
if (tmp == "Up")
{
direction = new Vector3(0, 0, 1);
} else if (tmp == "Down")
{
direction = new Vector3(0, 0, -1);
}else if(tmp == "Left")
{
direction = new Vector3(-1, 0, 0);
}else if(tmp == "Right")
{
direction = new Vector3(1, 0, 0);
}
else
{
direction = new Vector3(0, 0, 0);
}
Debug.Log(direction);
Debug.Log(tmp);
crate.Push(direction);
}
}
}
using UnityEngine;
using System.Collections;
public class Wall : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
using UnityEngine;
using System.Collections;
public class Crate : MonoBehaviour {
private Vector3 targetPosition;
private bool moving = false;
// Use this for initialization
void Start () {
this.targetPosition = this.transform.position;
}
// Update is called once per frame
void Update () {
if(this.transform.position == this.targetPosition)
{
this.moving = false;
return;
}
if (this.moving)
{
float step = 3.5f * Time.deltaTime;
this.transform.position = Vector3.MoveTowards(this.transform.position, this.targetPosition, step);
}
}
public void Push(Vector3 direction)
{
if (this.moving)
return;
if (Physics.Raycast(this.transform.position, direction, 0.4f))
{
this.moving = false;
return;
}
this.moving = true;
this.targetPosition = transform.position + direction;
Debug.Log(targetPosition);
}
}
I don't think it's a good idea to rely on collider sizes and sin widths and bounds. since your game is grid based you know the center points of each tile exactly. use this info ins$$anonymous$$d to move around
Thank you, i have found itween and use grid pixel movement ins$$anonymous$$d.
Your answer
![](https://koobas.hobune.stream/wayback/20220612064408im_/https://answers.unity.com/themes/thub/images/avi.jpg)