So I’m using a code that creates collider on shadow when the R key is pressed, and I want to make this collider visible (create a mesh component so player would see it in game). I need to do this in code, because collider is created by script, and those two have to be the sime size and shape.
on this screenshot the collider is not created yet
on this screenshot collider is active, and the player has jumped on the collider which I drew in paint where the mesh should be
Do you know how to do this?
(I’m a high school student, this is a year assigment for tomorrow so I don’t have time to change idea of a project)
here is the script I’ve been talking about
using UnityEngine;
using System.Linq;
public class InteractiveShadows : MonoBehaviour
{
[SerializeField] private Transform shadowTransform;
[SerializeField] private Transform lightTransform;
private LightType lightType;
[SerializeField] private LayerMask targetLayerMask;
[SerializeField] private Vector3 extrusionDirection = Vector3.zero;
private Vector3[] objectVertices;
private Mesh shadowColliderMesh;
private MeshCollider shadowCollider;
private Vector3 previousPosition;
private Quaternion previousRotation;
private Vector3 previousScale;
private bool canUpdateCollider = true;
private bool frezeCollider = false;
[SerializeField][Range(0.02f, 1f)] private float shadowColliderUpdateTime = 0.08f;
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
frezeCollider = !frezeCollider;
if(frezeCollider)
{
shadowCollider.isTrigger = false;
canUpdateCollider = false;
}
else
{
shadowCollider.isTrigger = true;
canUpdateCollider = true;
}
}
}
private void Awake()
{
if (frezeCollider == false)
{
InitializeShadowCollider();
lightType = lightTransform.GetComponent<Light>().type;
objectVertices = transform.GetComponent<MeshFilter>().mesh.vertices.Distinct().ToArray();
shadowColliderMesh = new Mesh();
}
}
void LateUpdate()
{
if (frezeCollider == false)
{
shadowTransform.position = transform.position;
}
}
private void FixedUpdate()
{
if (TransformHasChanged() && canUpdateCollider)
{
Invoke("UpdateShadowCollider", shadowColliderUpdateTime);
canUpdateCollider = false;
}
previousPosition = transform.position;
previousRotation = transform.rotation;
previousScale = transform.localScale;
}
private void InitializeShadowCollider()
{
GameObject shadowGameObject = shadowTransform.gameObject;
//shadowGameObject.hideFlags = HideFlags.HideInHierarchy; //OPTIONNAL
shadowCollider = shadowGameObject.AddComponent<MeshCollider>();
shadowCollider.convex = true;
shadowCollider.isTrigger = true;
}
private void UpdateShadowCollider()
{
shadowColliderMesh.vertices = ComputeShadowColliderMeshVertices();
shadowCollider.sharedMesh = shadowColliderMesh;
canUpdateCollider = true;
}
private Vector3[] ComputeShadowColliderMeshVertices()
{
Vector3[] points = new Vector3[2 * objectVertices.Length];
Vector3 raycastDirection = lightTransform.forward;
int n = objectVertices.Length;
for (int i = 0; i < n; i++)
{
Vector3 point = transform.TransformPoint(objectVertices[i]);
if (lightType != LightType.Directional)
{
raycastDirection = point - lightTransform.position;
}
points[i] = ComputeIntersectionPoint(point, raycastDirection);
points[n + i] = ComputeExtrusionPoint(point, points[i]);
}
return points;
}
private Vector3 ComputeIntersectionPoint(Vector3 fromPosition, Vector3 direction)
{
RaycastHit hit;
if (Physics.Raycast(fromPosition, direction, out hit, Mathf.Infinity, targetLayerMask))
{
return hit.point - transform.position;
}
return fromPosition + 100 * direction - transform.position;
}
private Vector3 ComputeExtrusionPoint(Vector3 objectVertexPosition, Vector3 shadowPointPosition)
{
if (extrusionDirection.sqrMagnitude == 0)
{
return objectVertexPosition - transform.position;
}
return shadowPointPosition + extrusionDirection;
}
private bool TransformHasChanged()
{
return previousPosition != transform.position || previousRotation != transform.rotation || previousScale != transform.localScale;
}
}