[TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
+8
fabriciorsz34
SantiMax
garden
Chilinger
MeverPlays
MarcosSchultz
Dom3000
anizioNoob
12 participantes
Página 1 de 1
[TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Olá pessoal, elaborei este script para deformar as mesh de qualquer objeto por ai, basta configurar...
O IDEAL PARA ESTE TUTORIAL É UTILIZAR MESH COLLIDER QUANDO FOR POSSÍVEL
Vídeo explicativo:
Script utilizado:
O IDEAL PARA ESTE TUTORIAL É UTILIZAR MESH COLLIDER QUANDO FOR POSSÍVEL
Vídeo explicativo:
Script utilizado:
- Código:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class Deformar : MonoBehaviour{
public MeshFilter[] meshes;
public Collider[] colisores;
[Range(1.0f,100.0f)] public float danoPorBatida = 2.0f;
[Range(0.1f,1000.0f)] public float areaDeDeform = 40.0f;
[Range(0.1f,10.0f)] public float MaximaDistorcao = 2.5f;
private int somaDosImpactos = 0;
private float proximoTempoImpacto = 0.0f;
private Vector3 somaPosicImpactos = Vector3.zero, somaVelocidadeImpactos = Vector3.zero;
private Vector3[][] meshesOriginais;
private Rigidbody rigidB;
void Start(){
rigidB = GetComponent<Rigidbody> ();
}
void OnEnable (){
meshesOriginais = new Vector3[meshes.Length][];//ajusta o tamanho do vetor ao numero de vertices
for (int i = 0; i < meshes.Length; i++){
Mesh mesh = meshes[i].mesh;
meshesOriginais[i] = mesh.vertices;//pega o local original de cada vertice e joga no vetor
mesh.MarkDynamic();
}
}
void OnDisable (){
for (int i = 0; i < meshes.Length; i++){
Mesh mesh = meshes[i].mesh;
mesh.vertices = meshesOriginais[i]; //realoca os vertices em seus lugares originais
mesh.RecalculateNormals(); //recalcula os Normals
mesh.RecalculateBounds(); //recalcula os Bounds
}
}
void OnCollisionEnter (Collision collision){
if (meshes.Length > 0 && colisores.Length > 0) {
int impactCount = 0;
Vector3 impactPosition = Vector3.zero, impactVelocity = Vector3.zero;
foreach (ContactPoint contact in collision.contacts) {
float dragRatio = Vector3.Dot (rigidB.GetPointVelocity (contact.point), contact.normal);
if (dragRatio < -0.6f || collision.relativeVelocity.sqrMagnitude > 3.0f) { //se tem velocidade o suficiente para ser uma colisao
impactCount++; //aumenta o numero de colisoes ocorridas
impactPosition += contact.point; //pega os lugares dos impactos
impactVelocity += collision.relativeVelocity; //pega as velocidades dos impactos
}
}
if (impactCount > 0) {//se tem mais de 0 impactos
float invCount = 1.0f / impactCount;
impactPosition *= invCount;
impactVelocity *= invCount;
somaDosImpactos++;
somaPosicImpactos += transform.InverseTransformPoint (impactPosition);
somaVelocidadeImpactos += transform.InverseTransformDirection (impactVelocity);
}
}
}
void FixedUpdate(){
if (meshes.Length > 0 && colisores.Length > 0) {
if (Time.time - proximoTempoImpacto >= 0.2f && somaDosImpactos > 0) {//tempo entre os impactos
float invCount = 1.0f / somaDosImpactos;
somaPosicImpactos *= invCount;
somaVelocidadeImpactos *= invCount;
Vector3 impactVelocity = Vector3.zero;
if (somaVelocidadeImpactos.sqrMagnitude > 1.5f) {
impactVelocity = transform.TransformDirection (somaVelocidadeImpactos) * 0.02f;
}
if (impactVelocity.sqrMagnitude > 0.0f) { //se a velocidade do impacto normalizada for maior do que 0.0f
Vector3 contactPoint = transform.TransformPoint (somaPosicImpactos);
for (int i = 0, c = meshes.Length; i < c; i++) {
DeformMesh (meshes [i].mesh, meshesOriginais [i], meshes [i].transform, contactPoint, impactVelocity); //chama o metodo que deforma as malhas e manda as informações
}
}
somaDosImpactos = 0;
somaPosicImpactos = Vector3.zero;
somaVelocidadeImpactos = Vector3.zero;
proximoTempoImpacto = Time.time + 0.2f * UnityEngine.Random.Range (-0.4f, 0.4f);
}
}
}
float DeformMesh (Mesh mesh, Vector3[] originalMesh, Transform localTransform, Vector3 contactPoint, Vector3 contactVelocity){
Vector3[] vertices = mesh.vertices;
Vector3 localContactPoint = localTransform.InverseTransformPoint(contactPoint);
Vector3 localContactForce = localTransform.InverseTransformDirection(contactVelocity);
float sqrMaxDeform = MaximaDistorcao * MaximaDistorcao;
float totalDamage = 0.0f;
int damagedVertices = 0;
for (int i=0; i<vertices.Length; i++){
float dist = (localContactPoint - vertices [i]).sqrMagnitude;//distancia entre o ponto de colisão e a mesh
if (dist < areaDeDeform){
Vector3 damage = (localContactForce * ((areaDeDeform*2.0f) - Mathf.Sqrt(dist)) / (areaDeDeform*2.0f))*(danoPorBatida*(1+rigidB.velocity.magnitude*0.2f)); //descobre o dano
vertices[i] += damage; //aplica o dano no vertice
Vector3 deform = vertices[i] - originalMesh[i]; //subtrai a posicao original do dano descoberto para chegar a nova posicao do vertice
if (deform.sqrMagnitude > sqrMaxDeform) {
vertices [i] = originalMesh [i] + deform.normalized * MaximaDistorcao;//normaliza danos absurdos
}
totalDamage += damage.magnitude;
damagedVertices++;
}
}
mesh.vertices = vertices; //aplica os novos vertices a malha
mesh.RecalculateNormals();
mesh.RecalculateBounds();
return damagedVertices > 0? totalDamage / damagedVertices : 0.0f;
}
}
Última edição por MarcosSchultz em Ter Jun 07, 2016 8:45 pm, editado 1 vez(es)
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Ótimo tutorial muito útil para nossos projetos. :D
Convidado- Convidado
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
vai dar pa fazer mta coisa irada com isso pena q não deforma o colisor pq ai sim seria awsome
anizioNoob- Avançado
- PONTOS : 3476
REPUTAÇÃO : 17
Idade : 22
Áreas de atuação : Sei programar animators, e modelar no sketchup
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
anizioNoob escreveu:vai dar pa fazer mta coisa irada com isso pena q não deforma o colisor pq ai sim seria awsome
Deformar colisor não é difícil, mas acaba tendo alguns bugs eventualmente, e é um tanto mais pesado para o projeto... Então acabei não incluindo.
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
muito bom cara, uma duvida tem como deformar o chao o Terreno, com isso tambem?MarcosSchultz escreveu:anizioNoob escreveu:vai dar pa fazer mta coisa irada com isso pena q não deforma o colisor pq ai sim seria awsome
Deformar colisor não é difícil, mas acaba tendo alguns bugs eventualmente, e é um tanto mais pesado para o projeto... Então acabei não incluindo.
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Com isto não... ele é feito para malhas, o Terrain é um pouco diferente, ele tem propriedades diferentes e até o colisor dele é diferente... tem que utilizar alguns metodos diferentes para alterar a sua mesh
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
entao é posivel faz uma Tuto disso
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
ta na lista jah... o GamesIndie já fez um tutorial disso uma vez, só que em javaScript.
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
que bom obrigado
onde eu acho esse poste ?
onde eu acho esse poste ?
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Marcos surgiu uma duvida se consigo deforma mesh tambem consigo destruir como no blender com sistema de destruiçao se tem como poderia fazer um tutorial ensinando ou mandar algo sobre o assunto.
Chilinger- MembroAvançado
- PONTOS : 4091
REPUTAÇÃO : 42
Idade : 30
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Realmente vai ser bem útil este tutorial :D
MeverPlays- Mestre
- PONTOS : 3867
REPUTAÇÃO : 48
Áreas de atuação : SketchUp, Unity.
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Da para destruir sim, tem até assets sobre isto... basta separar os triangulos da malha. Vou até anotar, para tentar elaborar algo quanto tiver tempo.
Chilinger- MembroAvançado
- PONTOS : 4091
REPUTAÇÃO : 42
Idade : 30
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Como faço para ex: Bater em uma pedra e ela começar a quebrar pedaços ?
garden- Iniciante
- PONTOS : 2804
REPUTAÇÃO : 1
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
garden escreveu:Como faço para ex: Bater em uma pedra e ela começar a quebrar pedaços ?
Pra isso você vai ter que ter um modelo já fraturado no blender
SantiMax- Iniciante
- PONTOS : 2726
REPUTAÇÃO : 0
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Marcos eu fiquei um tanto que curioso a respeito de se é possivel salvar esses danos , sim eu sei que dá mas qual é o metodo usado pra isso , hj eu lembrei desse seu tutorial e vim perguntar isso por mais que eu não use a colisão de mesh
agradeço desde já
agradeço desde já
fabriciorsz34- Avançado
- PONTOS : 3337
REPUTAÇÃO : 25
Idade : 24
Áreas de atuação : C#,unity,cinema 4D, SketchUp
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Olá @fabriciorsz34 , você já pensou na possibilidade de guardar os Vector3[] (As posições de cada vértice do Mesh) e depois aplicá-la novamente no Mesh Renderer?
NKKF- ProgramadorMaster
- PONTOS : 4817
REPUTAÇÃO : 574
Idade : 20
Áreas de atuação : Desenvolvedor na Unity, NodeJS, React, ReactJS, React Native, MongoDB e Firebase.
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
hmm, boaa ideia vou tentar
fabriciorsz34- Avançado
- PONTOS : 3337
REPUTAÇÃO : 25
Idade : 24
Áreas de atuação : C#,unity,cinema 4D, SketchUp
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
fabriciorsz34 escreveu:Marcos eu fiquei um tanto que curioso a respeito de se é possivel salvar esses danos , sim eu sei que dá mas qual é o metodo usado pra isso , hj eu lembrei desse seu tutorial e vim perguntar isso por mais que eu não use a colisão de mesh
agradeço desde já
Como assim "Guardar os danos"?
Existem várias maneiras de fazer isto, até da pra aplicar diretamente na mesh de modo que altere o modelo 3D em si, fazendo ele ficar deformado MESMO, como se você tivesse editado em um software de modelagem e depois importado... da pra fazer um monte de coisas.
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
consegui dar uma melhorada, porem parece que ta muito sensivel, qualquer coisinha ele deforma muito, qualquer coisa mesmo
nvndx- Membro
- PONTOS : 1969
REPUTAÇÃO : 2
Idade : 22
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
nvndx escreveu:consegui dar uma melhorada, porem parece que ta muito sensivel, qualquer coisinha ele deforma muito, qualquer coisa mesmo
É por causa da escala "errada" do seu modelo 3D... o ideal é que os modelos estejam em escalas compatíveis com as da Unity (1x1x1)
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
Estou tendo esses problemas com o script. Coloquei tudo da forma como mostra no vídeo. Alguém sabe me dizer como resolver?
Erros que aparecem:
Erros que aparecem:
- Código:
Not allowed to access vertices on mesh 'Paint_Geo_lodB Instance' (isReadable is false; Read/Write must be enabled in import settings)
UnityEngine.Mesh:get_vertices ()
Deform:DeformMesh (UnityEngine.Mesh,UnityEngine.Vector3[],UnityEngine.Transform,UnityEngine.Vector3,UnityEngine.Vector3) (at Assets/Scripts/Deform.cs:103)
Deform:FixedUpdate () (at Assets/Scripts/Deform.cs:90)
- Código:
Not allowed to access vertices on mesh 'Paint_Geo_lodB Instance' (isReadable is false; Read/Write must be enabled in import settings)
UnityEngine.Mesh:set_vertices (UnityEngine.Vector3[])
Deform:DeformMesh (UnityEngine.Mesh,UnityEngine.Vector3[],UnityEngine.Transform,UnityEngine.Vector3,UnityEngine.Vector3) (at Assets/Scripts/Deform.cs:125)
Deform:FixedUpdate () (at Assets/Scripts/Deform.cs:90)
- Código:
Not allowed to call RecalculateNormals() on mesh 'Paint_Geo_lodB Instance'
UnityEngine.Mesh:RecalculateNormals ()
Deform:DeformMesh (UnityEngine.Mesh,UnityEngine.Vector3[],UnityEngine.Transform,UnityEngine.Vector3,UnityEngine.Vector3) (at Assets/Scripts/Deform.cs:126)
Deform:FixedUpdate () (at Assets/Scripts/Deform.cs:90)
- Código:
Not allowed to call RecalculateBounds() on mesh 'Paint_Geo_lodB Instance'
UnityEngine.Mesh:RecalculateBounds ()
Deform:DeformMesh (UnityEngine.Mesh,UnityEngine.Vector3[],UnityEngine.Transform,UnityEngine.Vector3,UnityEngine.Vector3) (at Assets/Scripts/Deform.cs:127)
Deform:FixedUpdate () (at Assets/Scripts/Deform.cs:90)
WesFarias- Iniciante
- PONTOS : 2657
REPUTAÇÃO : 4
Respeito as regras :
Re: [TUTORIAL] Deformar mesh com batidas (para objetos, veículos, etc)
fiz uma alteração no Script
fiz ele clonar e reaplicar a malha dos veiculos, e inclui uma opção de skined mesh tambem, com isso resolve o um problema que tive que era quano o veiculo se deformava acaba aparecendo a mesma deformidade nos outros veiculos que usam a mesma malha.
fiz ele clonar e reaplicar a malha dos veiculos, e inclui uma opção de skined mesh tambem, com isso resolve o um problema que tive que era quano o veiculo se deformava acaba aparecendo a mesma deformidade nos outros veiculos que usam a mesma malha.
- Código:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class Deformar_Skined : MonoBehaviour
{
public SkinnedMeshRenderer[] skinnedMeshes;
public MeshFilter[] meshFilters; // Nova variável para as MeshFilters
public Collider[] colisores;
[Range(0.1f, 100.0f)] public float danoPorBatida = 2.0f;
[Range(0.1f, 1000.0f)] public float areaDeDeform = 40.0f;
[Range(0f, 10.0f)] public float MaximaDistorcao = 2.5f;
private int somaDosImpactos = 0;
private float proximoTempoImpacto = 0.0f;
private Vector3 somaPosicImpactos = Vector3.zero, somaVelocidadeImpactos = Vector3.zero;
private Vector3[][] skinnedMeshesOriginais; // Arrays para malhas originais
private Vector3[][] meshFiltersOriginais;
private Rigidbody rigidB;
void Start()
{
rigidB = GetComponent<Rigidbody>();
skinnedMeshesOriginais = new Vector3[skinnedMeshes.Length][];
for (int i = 0; i < skinnedMeshes.Length; i++)
{
Mesh originalMesh = skinnedMeshes[i].sharedMesh;
skinnedMeshesOriginais[i] = originalMesh.vertices.Clone() as Vector3[]; // Clonando os vértices originais
Mesh clonedMesh = Instantiate(originalMesh); // Clonando a mesh
skinnedMeshes[i].sharedMesh = clonedMesh; // Aplicando a mesh clonada no SkinnedMeshRenderer
clonedMesh.MarkDynamic();
}
meshFiltersOriginais = new Vector3[meshFilters.Length][];
for (int i = 0; i < meshFilters.Length; i++)
{
Mesh originalMesh = meshFilters[i].sharedMesh;
meshFiltersOriginais[i] = originalMesh.vertices.Clone() as Vector3[]; // Clonando os vértices originais
Mesh clonedMesh = Instantiate(originalMesh); // Clonando a mesh
meshFilters[i].sharedMesh = clonedMesh; // Aplicando a mesh clonada no MeshFilter
clonedMesh.MarkDynamic();
}
}
void OnEnable()
{
skinnedMeshesOriginais = new Vector3[skinnedMeshes.Length][];
for (int i = 0; i < skinnedMeshes.Length; i++)
{
Mesh mesh = skinnedMeshes[i].sharedMesh;
skinnedMeshesOriginais[i] = mesh.vertices;
mesh.MarkDynamic();
}
meshFiltersOriginais = new Vector3[meshFilters.Length][];
for (int i = 0; i < meshFilters.Length; i++)
{
Mesh mesh = meshFilters[i].sharedMesh;
meshFiltersOriginais[i] = mesh.vertices;
mesh.MarkDynamic();
}
}
void OnDisable()
{
for (int i = 0; i < skinnedMeshes.Length; i++)
{
Mesh mesh = skinnedMeshes[i].sharedMesh;
mesh.vertices = skinnedMeshesOriginais[i];
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
for (int i = 0; i < meshFilters.Length; i++)
{
Mesh mesh = meshFilters[i].sharedMesh;
mesh.vertices = meshFiltersOriginais[i];
mesh.RecalculateNormals();
mesh.RecalculateBounds();
}
}
void OnCollisionEnter(Collision collision)
{
if ((skinnedMeshes.Length > 0 || meshFilters.Length > 0) && colisores.Length > 0)
{
int impactCount = 0;
Vector3 impactPosition = Vector3.zero, impactVelocity = Vector3.zero;
foreach (ContactPoint contact in collision.contacts)
{
float dragRatio = Vector3.Dot(rigidB.GetPointVelocity(contact.point), contact.normal);
if (dragRatio < -0.6f || collision.relativeVelocity.sqrMagnitude > 3.0f)
{ //se tem velocidade o suficiente para ser uma colisao
impactCount++; //aumenta o numero de colisoes ocorridas
impactPosition += contact.point; //pega os lugares dos impactos
impactVelocity += collision.relativeVelocity; //pega as velocidades dos impactos
}
}
if (impactCount > 0)
{//se tem mais de 0 impactos
float invCount = 1.0f / impactCount;
impactPosition *= invCount;
impactVelocity *= invCount;
somaDosImpactos++;
somaPosicImpactos += transform.InverseTransformPoint(impactPosition);
somaVelocidadeImpactos += transform.InverseTransformDirection(impactVelocity);
}
}
}
void FixedUpdate()
{
if ((skinnedMeshes.Length > 0 || meshFilters.Length > 0) && colisores.Length > 0)
{
if (Time.time - proximoTempoImpacto >= 0.2f && somaDosImpactos > 0)
{//tempo entre os impactos
float invCount = 1.0f / somaDosImpactos;
somaPosicImpactos *= invCount;
somaVelocidadeImpactos *= invCount;
Vector3 impactVelocity = Vector3.zero;
if (somaVelocidadeImpactos.sqrMagnitude > 1.5f)
{
impactVelocity = transform.TransformDirection(somaVelocidadeImpactos) * 0.02f;
}
if (impactVelocity.sqrMagnitude > 0.0f)
{ //se a velocidade do impacto normalizada for maior do que 0.0f
Vector3 contactPoint = transform.TransformPoint(somaPosicImpactos);
for (int i = 0; i < skinnedMeshes.Length; i++)
{
DeformMesh(skinnedMeshes[i].sharedMesh, skinnedMeshesOriginais[i], skinnedMeshes[i].transform, contactPoint, impactVelocity); //chama o metodo que deforma as malhas e manda as informações
}
for (int i = 0; i < meshFilters.Length; i++)
{
DeformMesh(meshFilters[i].sharedMesh, meshFiltersOriginais[i], meshFilters[i].transform, contactPoint, impactVelocity); //chama o metodo que deforma as malhas e manda as informações
}
}
somaDosImpactos = 0;
somaPosicImpactos = Vector3.zero;
somaVelocidadeImpactos = Vector3.zero;
proximoTempoImpacto = Time.time + 0.2f * UnityEngine.Random.Range(-0.4f, 0.4f);
}
}
}
float DeformMesh(Mesh mesh, Vector3[] originalMesh, Transform localTransform, Vector3 contactPoint, Vector3 contactVelocity)
{
Vector3[] vertices = mesh.vertices;
Vector3 localContactPoint = localTransform.InverseTransformPoint(contactPoint);
Vector3 localContactForce = localTransform.InverseTransformDirection(contactVelocity);
float sqrMaxDeform = MaximaDistorcao * MaximaDistorcao;
float totalDamage = 0.0f;
int damagedVertices = 0;
for (int i = 0; i < vertices.Length; i++)
{
float dist = (localContactPoint - vertices[i]).sqrMagnitude;//distancia entre o ponto de colisão e a mesh
if (dist < areaDeDeform)
{
Vector3 damage = (localContactForce * ((areaDeDeform * 2.0f) - Mathf.Sqrt(dist)) / (areaDeDeform * 2.0f)) * (danoPorBatida * (1 + rigidB.velocity.magnitude * 0.2f)); //descobre o dano
vertices[i] += damage; //aplica o dano no vertice
Vector3 deform = vertices[i] - originalMesh[i]; //subtrai a posicao original do dano descoberto para chegar a nova posicao do vertice
if (deform.sqrMagnitude > sqrMaxDeform)
{
vertices[i] = originalMesh[i] + deform.normalized * MaximaDistorcao;//normaliza danos absurdos
}
totalDamage += damage.magnitude;
damagedVertices++;
}
}
mesh.vertices = vertices; //aplica os novos vertices a malha
mesh.RecalculateNormals();
mesh.RecalculateBounds();
return damagedVertices > 0 ? totalDamage / damagedVertices : 0.0f;
}
}
Yuri Heinz- Avançado
- PONTOS : 3613
REPUTAÇÃO : 38
Idade : 28
Respeito as regras :
Tópicos semelhantes
» [TUTORIAL] Como programar um VOLANTE para veículos
» Deformar mesh sem usar rigidbody e reconhecer força do impacto
» [TUTORIAL] Sistema simples para lançar objetos.
» [TUTORIAL] Melhorar a estabilidade dos veículos com Wheel Collider
» [TUTORIAL] Deformar o terreno
» Deformar mesh sem usar rigidbody e reconhecer força do impacto
» [TUTORIAL] Sistema simples para lançar objetos.
» [TUTORIAL] Melhorar a estabilidade dos veículos com Wheel Collider
» [TUTORIAL] Deformar o terreno
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos