Сложный вопрос - Форум Игроделов
Пн, 20 Май 2024, 13:57 
 
Приветствую Вас Гость Главная | Регистрация | Вход
Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум Игроделов » UNITY3D » ОБЩИЕ ВОПРОСЫ » Сложный вопрос (Подскажите)
Сложный вопрос
ramboДата: Сб, 02 Июн 2012, 15:46 | Сообщение # 1
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
Здраствуйте, у меня не легкий вопрос. Как или каким способом можно реализовать разрушение обьектов? Тоесть выстрелил в бетонное ограждение, а от него кусок отвалился. Зарание спасибо
 
СообщениеЗдраствуйте, у меня не легкий вопрос. Как или каким способом можно реализовать разрушение обьектов? Тоесть выстрелил в бетонное ограждение, а от него кусок отвалился. Зарание спасибо

Автор - rambo
Дата добавления - 02 Июн 2012 в 15:46
commandobyДата: Сб, 02 Июн 2012, 16:37 | Сообщение # 2
Unity 3D Free
 
Сообщений: 836
Награды: 3
Репутация: 211
Статус: Offline
Ударением старого и добавлением новых (разрушенных).

Блог.
 
СообщениеУдарением старого и добавлением новых (разрушенных).

Автор - commandoby
Дата добавления - 02 Июн 2012 в 16:37
ramboДата: Сб, 02 Июн 2012, 17:55 | Сообщение # 3
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
нашел код) но не уверен что он работает
Code

var fractureToPoint = false;
var totalMaxFractures = 3;
var forcePerDivision = 20.0;
var minBreakingForce = 0.0;
var maxFracturesPerCall = 3;
var randomOffset = 0.0;
var minFractureSize : Vector3 = Vector3.zero;
var grain : Vector3 = Vector3.one;
var useCollisionDirection = 0.0;
var fractureAtCenter = false;
var smartJoints = false;
var destroyAllAfterTime = 0.0;
var destroySmallAfterTime = 0.0;
var instantiateOnBreak : GameObject;
var totalMassIfStatic = 1.0;
private var joints : Joint[];
//-------------------------------------------------------------------
function Start () {
  if (rigidbody) {
   temp = new Array();
   for(j in FindObjectsOfType(Joint)) {
    if (j.connectedBody == rigidbody) {
     temp.Add(j);
     joints  = temp.ToBuiltin(Joint);
    }
   }
  }
}
//-------------------------------------------------------------------
function OnCollisionEnter (collision : Collision) {
  point=collision.contacts[0].point;
  vec = collision.relativeVelocity*UsedMass(collision);
  FractureAtPoint(point,vec);
}
//-------------------------------------------------------------------
function FractureAtPoint (hit : Vector3, force : Vector3) {
  if (force.magnitude < Mathf.Max(minBreakingForce,forcePerDivision)) {return;}
  iterations =  Mathf.Min(Mathf.RoundToInt(force.magnitude/forcePerDivision),Mathf.Min(maxFracturesPerCall,totalMaxFractures));
  point = transform.worldToLocalMatrix.MultiplyPoint(hit);
  Fracture(point,force,iterations);
}
//-------------------------------------------------------------------
function Fracture (point : Vector3, force : Vector3, iterations : float) {
  if (instantiateOnBreak && force.magnitude >= Mathf.Max(minBreakingForce,forcePerDivision)) {
   Instantiate(instantiateOnBreak,transform.position,transform.rotation);
   instantiateOnBreak = null;
  }
  while (iterations > 0) {
   // if we are smaller than our minimum fracture size in any dimension, no more divisions.
   if (totalMaxFractures == 0 || Vector3.Min(gameObject.GetComponent(MeshFilter).mesh.bounds.size,minFractureSize) != minFractureSize) {
    if (destroySmallAfterTime >= 1) {
     Destroy(GetComponent(MeshCollider),destroySmallAfterTime-1);
     Destroy(gameObject,destroySmallAfterTime);
    }
    totalMaxFractures = 0;
    return;
   }
   totalMaxFractures -= 1;
   iterations -= 1;
   // define the splitting plane by the user settings.
   if(fractureAtCenter){point=GetComponent(MeshFilter).mesh.bounds.center;}
   vec = Vector3.Scale(grain,Random.insideUnitSphere).normalized;
   sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*useCollisionDirection*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector( force.normalized),vec);
   plane = Plane(vec-sub,Vector3.Scale(Random.insideUnitSphere,GetComponent(MeshFilter).mesh.bounds.size)*randomOffset+point);
   // create the clone
   newObject = Instantiate(gameObject,transform.position,transform.rotation);
   if (rigidbody) {newObject.rigidbody.velocity = rigidbody.velocity;}
   // arrays of the verts
   var vertsA =  gameObject.GetComponent(MeshFilter).mesh.vertices;
   var vertsB =  newObject.GetComponent(MeshFilter).mesh.vertices;
   average = Vector3.zero;
   for (i in vertsA) {
    average += i;
   }
   average /= gameObject.GetComponent(MeshFilter).mesh.vertexCount;
   average -= plane.GetDistanceToPoint(average)*plane.normal;
   //-------------------------------------------------------------------
   broken = 0;
   // split geometry along plane
   if (fractureToPoint) {
    for (i=0;i<gameObject.GetComponent(MeshFilter).mesh.vertexCount;i++) {
     if (plane.GetSide(vertsA[i])) {
      vertsA[i] = average;
      broken += 1;
     }
     else {
      vertsB[i] = average;
     }
    }
   }
   else {
    for (i=0;i<gameObject.GetComponent(MeshFilter).mesh.vertexCount;i++) {
     if (plane.GetSide(vertsA[i])) {
      vertsA[i] -= plane.GetDistanceToPoint(vertsA[i])*plane.normal;
      broken += 1;
     }
     else {
      vertsB[i] -= plane.GetDistanceToPoint(vertsB[i])*plane.normal;
     }
    }
   }
   // IMPORTANT: redo if we have a problem splitting; without this, we will get a lot of non-manifold meshes, convexhull errors and maybe even crash the game.
   if (broken == 0 || broken == gameObject.GetComponent(MeshFilter).mesh.vertexCount) {
    totalMaxFractures += 1;
    iterations += 1;
    Destroy(newObject);
    // this yield is here JUST so that when a large amount of objects are being broken, the screen doesn't freeze for a long time. It allows the screen to refresh before we're finnished, but if you don't, it might slow the script down trying to break a loop of bad planes.
    yield;
   }
   // if all's fine, apply the changes to each mesh
   else {
    gameObject.GetComponent(MeshFilter).mesh.vertices = vertsA;
    newObject.GetComponent(MeshFilter).mesh.vertices = vertsB;
    gameObject.GetComponent(MeshFilter).mesh.RecalculateNormals();
    newObject.GetComponent(MeshFilter).mesh.RecalculateNormals();
    gameObject.GetComponent(MeshFilter).mesh.RecalculateBounds();
    newObject.GetComponent(MeshFilter).mesh.RecalculateBounds();
    if (gameObject.GetComponent(MeshCollider)) {
     gameObject.GetComponent(MeshCollider).sharedMesh = gameObject.GetComponent(MeshFilter).mesh;
     newObject.GetComponent(MeshCollider).sharedMesh = newObject.GetComponent(MeshFilter).mesh;
    }
    // if we weren't using a convexhull, the pieces colliders won't work right. It's best for everyone if we just remove them.
    else {
     Destroy(collider);
     Destroy(gameObject,1);
    }
    // smartjoints will allow joints to function properly.
    if (smartJoints) {
     jointsb = GetComponents(Joint);
     if (jointsb){
      // Basically, it goes through each joint and sees if the object A or B are closer to the connected body. Whichever is closer keeps the joint.
      for (i=0;i<jointsb.length;i++){
       if (jointsb[i].connectedBody != null && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(jointsb[i].connectedBody.transform.position))) {
        if (jointsb[i].gameObject.GetComponent(SimpleFracture).joints) {
         // If we're attached to a fracture object and the new object is closer, switch the connected object's joint variable at the correct index.
         for (c in jointsb[i].gameObject.GetComponent(SimpleFracture).joints) {
          if (c == jointsb[i]) {c = newObject.GetComponents(Joint)[i];}
         }
        }
        Destroy(jointsb[i]);
       }
       else {
        Destroy(newObject.GetComponents(Joint)[i]);
       }
      }
     }
     // joints contains all joints this object is attached to. It checks if the joint still exists, and if the new object is closer. If so, changes the connection. It then removes the joint from the joints variable at the correct index.
     if (joints){
      for (i=0;i<joints.length;i++){
       if (joints[i] && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(joints[i].transform.position))) {
        joints[i].connectedBody = newObject.rigidbody;
        temp = new Array(joints);
        temp.RemoveAt(i);
        joints = temp.ToBuiltin(Joint);
       }
       else {
        temp = new Array(joints);
        temp.RemoveAt(i);
        newObject.GetComponent(SimpleFracture).joints = temp.ToBuiltin(Joint);
       }
      }
     }
    }
    // if we don't have smartJoints, the code is much shorter. destroy all joints.
    else {
     if (GetComponent(Joint)) {
      for (i=0;i<GetComponents(Joint).length;i++){
       Destroy(GetComponents(Joint)[i]);
       Destroy(newObject.GetComponents(Joint)[i]);
      }
     }
     if (joints) {
      for (i=0;i<joints.length;i++){
       Destroy(joints[i]);
      }
      joints = null;
     }
    }
    // if the script is attached to a static object, make it dynamic. If not, divide the mass up.
    if (!rigidbody) {
     gameObject.AddComponent(Rigidbody);
     newObject.AddComponent(Rigidbody);
     rigidbody.mass = totalMassIfStatic;
     newObject.rigidbody.mass = totalMassIfStatic;
    }
    gameObject.rigidbody.mass *= 0.5;
    newObject.rigidbody.mass *= 0.5;
    gameObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(gameObject.collider.bounds.center);
    newObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(newObject.collider.bounds.center);
     
    newObject.GetComponent(SimpleFracture).Fracture(point,force,iterations);
     
    if (destroyAllAfterTime >= 1) {
     Destroy(newObject.GetComponent(MeshCollider),destroyAllAfterTime-1);
     Destroy(GetComponent(MeshCollider),destroyAllAfterTime-1);
     Destroy(newObject,destroyAllAfterTime);
     Destroy(gameObject,destroyAllAfterTime);
    }
    // this yield is here JUST so that when a large amount of objects are being broken, the screen doesn't freeze for a while.
    yield;
   }// if not broken end
  }// while itterations end
  if (totalMaxFractures == 0 || Vector3.Min(gameObject.GetComponent(MeshFilter).mesh.bounds.size,minFractureSize) != minFractureSize) {
   if (destroySmallAfterTime >= 1) {
    Destroy(GetComponent(MeshCollider),destroySmallAfterTime-1);
    Destroy(gameObject,destroySmallAfterTime);
   }
   totalMaxFractures = 0;
  }
}
//--------------------------------------------------------------
function UsedMass (collision : Collision) {
  if (collision.rigidbody) {
   if (rigidbody) {
    if (collision.rigidbody.mass < rigidbody.mass) {
     return (collision.rigidbody.mass);
    }
    else {
     return (rigidbody.mass);
    }
   }
   else {
    return (collision.rigidbody.mass);
   }
  }
  else if (rigidbody) {
   return (rigidbody.mass);
  }
  else {return (1);}
}
 
Сообщениенашел код) но не уверен что он работает
Code

var fractureToPoint = false;
var totalMaxFractures = 3;
var forcePerDivision = 20.0;
var minBreakingForce = 0.0;
var maxFracturesPerCall = 3;
var randomOffset = 0.0;
var minFractureSize : Vector3 = Vector3.zero;
var grain : Vector3 = Vector3.one;
var useCollisionDirection = 0.0;
var fractureAtCenter = false;
var smartJoints = false;
var destroyAllAfterTime = 0.0;
var destroySmallAfterTime = 0.0;
var instantiateOnBreak : GameObject;
var totalMassIfStatic = 1.0;
private var joints : Joint[];
//-------------------------------------------------------------------
function Start () {
  if (rigidbody) {
   temp = new Array();
   for(j in FindObjectsOfType(Joint)) {
    if (j.connectedBody == rigidbody) {
     temp.Add(j);
     joints  = temp.ToBuiltin(Joint);
    }
   }
  }
}
//-------------------------------------------------------------------
function OnCollisionEnter (collision : Collision) {
  point=collision.contacts[0].point;
  vec = collision.relativeVelocity*UsedMass(collision);
  FractureAtPoint(point,vec);
}
//-------------------------------------------------------------------
function FractureAtPoint (hit : Vector3, force : Vector3) {
  if (force.magnitude < Mathf.Max(minBreakingForce,forcePerDivision)) {return;}
  iterations =  Mathf.Min(Mathf.RoundToInt(force.magnitude/forcePerDivision),Mathf.Min(maxFracturesPerCall,totalMaxFractures));
  point = transform.worldToLocalMatrix.MultiplyPoint(hit);
  Fracture(point,force,iterations);
}
//-------------------------------------------------------------------
function Fracture (point : Vector3, force : Vector3, iterations : float) {
  if (instantiateOnBreak && force.magnitude >= Mathf.Max(minBreakingForce,forcePerDivision)) {
   Instantiate(instantiateOnBreak,transform.position,transform.rotation);
   instantiateOnBreak = null;
  }
  while (iterations > 0) {
   // if we are smaller than our minimum fracture size in any dimension, no more divisions.
   if (totalMaxFractures == 0 || Vector3.Min(gameObject.GetComponent(MeshFilter).mesh.bounds.size,minFractureSize) != minFractureSize) {
    if (destroySmallAfterTime >= 1) {
     Destroy(GetComponent(MeshCollider),destroySmallAfterTime-1);
     Destroy(gameObject,destroySmallAfterTime);
    }
    totalMaxFractures = 0;
    return;
   }
   totalMaxFractures -= 1;
   iterations -= 1;
   // define the splitting plane by the user settings.
   if(fractureAtCenter){point=GetComponent(MeshFilter).mesh.bounds.center;}
   vec = Vector3.Scale(grain,Random.insideUnitSphere).normalized;
   sub = transform.worldToLocalMatrix.MultiplyVector(force.normalized)*useCollisionDirection*Vector3.Dot(transform.worldToLocalMatrix.MultiplyVector( force.normalized),vec);
   plane = Plane(vec-sub,Vector3.Scale(Random.insideUnitSphere,GetComponent(MeshFilter).mesh.bounds.size)*randomOffset+point);
   // create the clone
   newObject = Instantiate(gameObject,transform.position,transform.rotation);
   if (rigidbody) {newObject.rigidbody.velocity = rigidbody.velocity;}
   // arrays of the verts
   var vertsA =  gameObject.GetComponent(MeshFilter).mesh.vertices;
   var vertsB =  newObject.GetComponent(MeshFilter).mesh.vertices;
   average = Vector3.zero;
   for (i in vertsA) {
    average += i;
   }
   average /= gameObject.GetComponent(MeshFilter).mesh.vertexCount;
   average -= plane.GetDistanceToPoint(average)*plane.normal;
   //-------------------------------------------------------------------
   broken = 0;
   // split geometry along plane
   if (fractureToPoint) {
    for (i=0;i<gameObject.GetComponent(MeshFilter).mesh.vertexCount;i++) {
     if (plane.GetSide(vertsA[i])) {
      vertsA[i] = average;
      broken += 1;
     }
     else {
      vertsB[i] = average;
     }
    }
   }
   else {
    for (i=0;i<gameObject.GetComponent(MeshFilter).mesh.vertexCount;i++) {
     if (plane.GetSide(vertsA[i])) {
      vertsA[i] -= plane.GetDistanceToPoint(vertsA[i])*plane.normal;
      broken += 1;
     }
     else {
      vertsB[i] -= plane.GetDistanceToPoint(vertsB[i])*plane.normal;
     }
    }
   }
   // IMPORTANT: redo if we have a problem splitting; without this, we will get a lot of non-manifold meshes, convexhull errors and maybe even crash the game.
   if (broken == 0 || broken == gameObject.GetComponent(MeshFilter).mesh.vertexCount) {
    totalMaxFractures += 1;
    iterations += 1;
    Destroy(newObject);
    // this yield is here JUST so that when a large amount of objects are being broken, the screen doesn't freeze for a long time. It allows the screen to refresh before we're finnished, but if you don't, it might slow the script down trying to break a loop of bad planes.
    yield;
   }
   // if all's fine, apply the changes to each mesh
   else {
    gameObject.GetComponent(MeshFilter).mesh.vertices = vertsA;
    newObject.GetComponent(MeshFilter).mesh.vertices = vertsB;
    gameObject.GetComponent(MeshFilter).mesh.RecalculateNormals();
    newObject.GetComponent(MeshFilter).mesh.RecalculateNormals();
    gameObject.GetComponent(MeshFilter).mesh.RecalculateBounds();
    newObject.GetComponent(MeshFilter).mesh.RecalculateBounds();
    if (gameObject.GetComponent(MeshCollider)) {
     gameObject.GetComponent(MeshCollider).sharedMesh = gameObject.GetComponent(MeshFilter).mesh;
     newObject.GetComponent(MeshCollider).sharedMesh = newObject.GetComponent(MeshFilter).mesh;
    }
    // if we weren't using a convexhull, the pieces colliders won't work right. It's best for everyone if we just remove them.
    else {
     Destroy(collider);
     Destroy(gameObject,1);
    }
    // smartjoints will allow joints to function properly.
    if (smartJoints) {
     jointsb = GetComponents(Joint);
     if (jointsb){
      // Basically, it goes through each joint and sees if the object A or B are closer to the connected body. Whichever is closer keeps the joint.
      for (i=0;i<jointsb.length;i++){
       if (jointsb[i].connectedBody != null && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(jointsb[i].connectedBody.transform.position))) {
        if (jointsb[i].gameObject.GetComponent(SimpleFracture).joints) {
         // If we're attached to a fracture object and the new object is closer, switch the connected object's joint variable at the correct index.
         for (c in jointsb[i].gameObject.GetComponent(SimpleFracture).joints) {
          if (c == jointsb[i]) {c = newObject.GetComponents(Joint)[i];}
         }
        }
        Destroy(jointsb[i]);
       }
       else {
        Destroy(newObject.GetComponents(Joint)[i]);
       }
      }
     }
     // joints contains all joints this object is attached to. It checks if the joint still exists, and if the new object is closer. If so, changes the connection. It then removes the joint from the joints variable at the correct index.
     if (joints){
      for (i=0;i<joints.length;i++){
       if (joints[i] && plane.GetSide(transform.worldToLocalMatrix.MultiplyPoint(joints[i].transform.position))) {
        joints[i].connectedBody = newObject.rigidbody;
        temp = new Array(joints);
        temp.RemoveAt(i);
        joints = temp.ToBuiltin(Joint);
       }
       else {
        temp = new Array(joints);
        temp.RemoveAt(i);
        newObject.GetComponent(SimpleFracture).joints = temp.ToBuiltin(Joint);
       }
      }
     }
    }
    // if we don't have smartJoints, the code is much shorter. destroy all joints.
    else {
     if (GetComponent(Joint)) {
      for (i=0;i<GetComponents(Joint).length;i++){
       Destroy(GetComponents(Joint)[i]);
       Destroy(newObject.GetComponents(Joint)[i]);
      }
     }
     if (joints) {
      for (i=0;i<joints.length;i++){
       Destroy(joints[i]);
      }
      joints = null;
     }
    }
    // if the script is attached to a static object, make it dynamic. If not, divide the mass up.
    if (!rigidbody) {
     gameObject.AddComponent(Rigidbody);
     newObject.AddComponent(Rigidbody);
     rigidbody.mass = totalMassIfStatic;
     newObject.rigidbody.mass = totalMassIfStatic;
    }
    gameObject.rigidbody.mass *= 0.5;
    newObject.rigidbody.mass *= 0.5;
    gameObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(gameObject.collider.bounds.center);
    newObject.rigidbody.centerOfMass = transform.worldToLocalMatrix.MultiplyPoint3x4(newObject.collider.bounds.center);
     
    newObject.GetComponent(SimpleFracture).Fracture(point,force,iterations);
     
    if (destroyAllAfterTime >= 1) {
     Destroy(newObject.GetComponent(MeshCollider),destroyAllAfterTime-1);
     Destroy(GetComponent(MeshCollider),destroyAllAfterTime-1);
     Destroy(newObject,destroyAllAfterTime);
     Destroy(gameObject,destroyAllAfterTime);
    }
    // this yield is here JUST so that when a large amount of objects are being broken, the screen doesn't freeze for a while.
    yield;
   }// if not broken end
  }// while itterations end
  if (totalMaxFractures == 0 || Vector3.Min(gameObject.GetComponent(MeshFilter).mesh.bounds.size,minFractureSize) != minFractureSize) {
   if (destroySmallAfterTime >= 1) {
    Destroy(GetComponent(MeshCollider),destroySmallAfterTime-1);
    Destroy(gameObject,destroySmallAfterTime);
   }
   totalMaxFractures = 0;
  }
}
//--------------------------------------------------------------
function UsedMass (collision : Collision) {
  if (collision.rigidbody) {
   if (rigidbody) {
    if (collision.rigidbody.mass < rigidbody.mass) {
     return (collision.rigidbody.mass);
    }
    else {
     return (rigidbody.mass);
    }
   }
   else {
    return (collision.rigidbody.mass);
   }
  }
  else if (rigidbody) {
   return (rigidbody.mass);
  }
  else {return (1);}
}

Автор - rambo
Дата добавления - 02 Июн 2012 в 17:55
QNicolyaДата: Сб, 02 Июн 2012, 18:05 | Сообщение # 4
God gave Rock'N'Roll to you
 
Сообщений: 3369
Награды: 3
Репутация: 352
Статус: Offline
Quote (rambo)
нашел код) но не уверен что он работает

Так проверь. В чем проблема?


Если человек вас обманул - он мошенник, если он вас обманул дважды - вы дурак.
 
Сообщение
Quote (rambo)
нашел код) но не уверен что он работает

Так проверь. В чем проблема?

Автор - QNicolya
Дата добавления - 02 Июн 2012 в 18:05
ramboДата: Сб, 02 Июн 2012, 18:09 | Сообщение # 5
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
QNicolya, у меня не работает, или я чтото не так делаю(
 
СообщениеQNicolya, у меня не работает, или я чтото не так делаю(

Автор - rambo
Дата добавления - 02 Июн 2012 в 18:09
Форум Игроделов » UNITY3D » ОБЩИЕ ВОПРОСЫ » Сложный вопрос (Подскажите)
  • Страница 1 из 1
  • 1
Поиск:
Загрузка...

Game Creating CommUnity © 2009 - 2024