v.0.1.2 Released
Physics Box » Devlog
This was a good practice to learn how one can deform 3d vertices in Unity. Once a mesh is readable/writable, it is a piece of cake.
Here is the full script to enable the deformation.
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(MeshCollider), typeof(MeshFilter))] public class DeformableObject : ClickableObject { [SerializeField] private float softness = 0.05f; [SerializeField] private float impactRadius = 0.1f; [SerializeField] private float springness = 0.5f; [SerializeField] private float touchImpactMagnitude = 25.0f; [SerializeField] private float maxVertexDispositionRadius = 0.2f; private MeshCollider meshColliderComp = null; private Mesh meshComp = null; private Vector3[] initialVertices = null; private Vector3[] vertices = null; private void Awake() { meshColliderComp = GetComponent<meshcollider>(); MeshFilter meshFilter = GetComponent<meshfilter>(); if (meshFilter != null) { meshComp = meshFilter.mesh; } Debug.Assert(meshColliderComp != null || meshComp != null); initialVertices = meshComp.vertices; } private void OnCollisionEnter(Collision collision) { // Use single contact point for now. Vector3 impactPoint = transform.InverseTransformPoint(collision.GetContact(0).point); Vector3 impactNormal = transform.InverseTransformDirection(collision.GetContact(0).normal); float impulseMagnitude = collision.impulse.magnitude; DeformMesh(impactPoint, impactNormal, impulseMagnitude); } private void FixedUpdate() { vertices = meshComp.vertices; int vertexCount = vertices.Length; for (int i = 0; i < vertexCount; ++i) { float alpha = Mathf.Clamp(springness * Time.fixedDeltaTime, 0.0f, 1.0f); vertices[i] = Vector3.Lerp(vertices[i], initialVertices[i], alpha); } meshComp.vertices = vertices; meshColliderComp.sharedMesh = meshComp; meshComp.RecalculateNormals(); meshComp.RecalculateBounds(); } public override void Click(ClickEvent cEvent) { base.Click(cEvent); Vector3 impactPoint = transform.InverseTransformPoint(cEvent.position); Vector3 impactNormal = transform.InverseTransformDirection(cEvent.direction); DeformMesh(impactPoint, impactNormal, touchImpactMagnitude); } private void DeformMesh(Vector3 impactPoint, Vector3 impactNormal, float impulseMagnitude) { vertices = meshComp.vertices; float scale = 1.0f; int vertexCount = vertices.Length; for (int i = 0; i < vertexCount; ++i) { scale = Mathf.Clamp(impactRadius - (impactPoint - vertices[i]).magnitude, 0.0f, impactRadius); scale = Mathf.Clamp(impulseMagnitude * scale * softness, 0.0f, maxVertexDispositionRadius); vertices[i] += impactNormal * scale; } meshComp.vertices = vertices; meshColliderComp.sharedMesh = meshComp; meshComp.RecalculateNormals(); meshComp.RecalculateBounds(); } private void OnApplicationQuit() { meshComp.vertices = initialVertices; } }
You can access all the files from the git repo.
Currently, this code is not optimized at all! I am reassigning its vertices each frame and also making it recalculate its normals and bounds. This is not a quality code at all. But, my purpose was to do a quick deformable mesh so this covers it. I may refactor it to be more optimized later (this means it will stay this way).
Files
PhysicsBox_v_0_1_2.zip 8 MB
Sep 01, 2020
Get Physics Box
Physics Box
A Small Playing Box With Interactive Physics Objects
Status | In development |
Author | Kenan Maraşlı |
Genre | Simulation |
Tags | Physics, Unity |
More posts
- v.0.1.1 ReleasedAug 31, 2020
- v.0.1.0 ReleasedAug 25, 2020
Leave a comment
Log in with itch.io to leave a comment.