Hi All !
I’m developing a game on which everything is slow, you take your time to reach a point, enjoy the landscape… Semi-contemplation game on which you are a snail.
A good challenge because as a snail, you are allowed to move on almost every surfaces. I decided to start using just a cube and try to figure out the mechanics.
I’ve read a lot here and there, and came up with using raycasts. So far it works great as I can climb any sort of surface with the layer tag “ground”. Some empty objects are attached to the cube and oriented so their ray is oriented to the ground at different locations so I can calculate the average normal of the ground. Then I rotate the cube.
Here is the script and what I have.
https://drive.google.com/file/d/11Kh6iB6AKqtN3NSOKw_WwQeeVdAFFpRZ/view?usp=sharing
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GetNormalRaycast : MonoBehaviour
{
public LayerMask mask;
public float groundCheckLength = 1;
public float leftCheckLength = 1;
public float middleCheckLength = 1;
public float rightCheckLength = 1;
public Transform groundChecker;
public Transform leftChecker;
public Transform middleChecker;
public Transform rightChecker;
private Vector3 groundNormal;
private Vector3 MiddleNormal;
public float speed = 1;
public float rotationSpeed = 50;
// Update is called once per frame
void Update(){
if (Input.GetAxis("Vertical") != 0 ){
// Ground
//Ray ray = new Ray(transform.position, transform.up * -1.0f);
Ray groundRay = new Ray(groundChecker.position, groundChecker.forward);
RaycastHit groundHitInfo;
if (Physics.Raycast(groundRay, out groundHitInfo, groundCheckLength, mask)){
Debug.DrawLine(groundRay.origin, groundHitInfo.point, Color.red);
Quaternion surfaceRot = Quaternion.FromToRotation (Vector3.up, groundHitInfo.normal);
Quaternion newRot = surfaceRot * Quaternion.AngleAxis(transform.rotation.eulerAngles.y, Vector3.up);
groundNormal = groundHitInfo.normal;
//transform.rotation = Quaternion.Slerp(transform.rotation, newRot, 0.1f);
//Vector3 currentPos = transform.position;
//Vector3 newPos = groundHitInfo.point + new Vector3(0f,0.5f,0f);
//transform.position = Vector3.Slerp(currentPos,newPos, 0.1f);
}else{
Debug.DrawLine(groundRay.origin, groundRay.origin + groundRay.direction *groundCheckLength, Color.green);
//groundCheckLength += groundCheckLength;
groundNormal = new Vector3(0f,0f,0f);
}
//Middle checker
Ray MiddleRay = new Ray(middleChecker.position, middleChecker.forward);
RaycastHit middleHitInfo;
if (Physics.Raycast(MiddleRay, out middleHitInfo, middleCheckLength, mask)){
Debug.DrawLine(MiddleRay.origin, middleHitInfo.point, Color.red);
Quaternion surfaceRot = Quaternion.FromToRotation (Vector3.up, middleHitInfo.normal);
Quaternion newRot = surfaceRot * Quaternion.AngleAxis(transform.rotation.eulerAngles.y, Vector3.up);
MiddleNormal = middleHitInfo.normal;
}else{
Debug.DrawLine(MiddleRay.origin, MiddleRay.origin + MiddleRay.direction *middleCheckLength, Color.green);
MiddleNormal = new Vector3(0f,0f,0f);
//middleCheckLength += middleCheckLength;
}
//float horizontalData = Input.GetAxis("Horizontal");
//Vector3 horizontalforce = new Vector3(0f, horizontalData, 0f);
Vector3 averageNormal = ((groundNormal + MiddleNormal) / 2);
Quaternion targetRotation = Quaternion.FromToRotation(Vector3.up, averageNormal);
//Debug.Log("X : " + targetRotation.eulerAngles.x);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 0.08f);
//transform.Rotate(targetRotation.eulerAngles.z,targetRotation.eulerAngles.x, 0f, Space.Self);
transform.Translate(Vector3.forward * speed * Time.smoothDeltaTime, Space.Self);
}
if(Input.GetAxis("Horizontal") != 0){
transform.Rotate(0,rotationSpeed * Time.deltaTime * Input.GetAxis("Horizontal"), 0);
}
}
}
The problem is that I can only go forward, no turns allowed. Also the cube is not “touching” the ground.
I kind of know where this happens, because I apply a rotation every time the player presses the vertical input.
Of course the cube has to be allowed to go left and right (not backward though).
I’m kinda stuck now, I thought I could somehow get the float value of the Horizontal input, map it to a min and max angle and construct a vector3 with it, then add the value to the Quaternion… but not to avail for now.
Maybe I’m not taking the problem by the right end.
If you end up having a brilliant idea for me, I would really appreciate it ^^
Have a good day !
Martin