简体   繁体   English

在2个游戏对象之间生成游戏对象

[英]Spawning game object between 2 game objects in unity

I am a beginner in Unity and C# and I am trying to create a molecule game object from 2 atom game objects. 我是Unity和C#的初学者,我试图从2个原子游戏对象创建一个分子游戏对象。 Main concept here is when 2 atoms game objects will come closer to each other they will kind of react and try to form a bond. 这里的主要概念是,当2个原子的游戏对象彼此靠近时,它们会做出反应并尝试形成结合。

So what I am trying to do currently is spawning a cylindrical game object(as a bond) between both atom game objects. 因此,我目前正在尝试在两个原子游戏对象之间生成一个圆柱形游戏对象(作为键)。 I am successful in spawning cylinder between atom objects but I am stuck with positioning that cylinder properly between those 2 atoms game objects. 我成功地在原子对象之间生成了圆柱体,但是我坚持将那个圆柱体正确地定位在这两个原子游戏对象之间。

This is what it looks like currently 这是目前的样子

分子图像

This is my code for creating molecule 这是我创建分子的代码

 private IEnumerator DelayedMoleculeFormation(Atom atomOne, Atom atomTwo)
{
    yield return 0;

    if (atomOne == null || atomTwo == null) yield return 0;

    Transform atomOneTransform = atomOne.transform; // Transform of first atom
    Transform atomTwoTransform = atomTwo.transform; // Transform of second atom

    GameObject atomOneGameObject = atomOne.gameObject; //GameObject of first atom
    GameObject atomTwoGameObject = atomTwo.gameObject;  //GameObject of second atom

    // if both atoms are ready to form bonds
    //if (CanFormBond(atomOne, atomTwo)) this check is not required (nor should be done again) as DelayedMoleculeFormation will only be called if it already passed 
    // CanFormBond will also change reactiveCount so consecutive CanFormBond can return false
    {
        #region AddBond

        Transform atomOneReference = null, atomTwoReference = null;

        GameObject molecule = null;

        if(atomOne.isConsumed)
        {
            if(atomOne.transform.parent) //If an atom is inside a molecule
            molecule = atomOne.transform.parent.gameObject;
        }
        else if (atomTwo.isConsumed)
        {
            if(atomTwo.transform.parent) //if atom two is inside a molecule
            molecule = atomTwo.transform.parent.gameObject;
        }


        if (atomOne.isConsumed)
        {
            atomOneReference = atomOneTransform;
            atomTwoReference = atomTwoTransform;

            atomTwoTransform.LookAt(atomOneTransform.position);
        }
        else
        {
            atomOneReference = atomTwoTransform;
            atomTwoReference = atomOneTransform;

            atomOneTransform.LookAt(atomTwoTransform.position);
        }


        if (molecule == null)
        {
            molecule = Instantiate(Resources.Load("MoleculePrefab")) as GameObject;

            var pos = (atomTwo.transform.position - atomOne.transform.position) / 2.0f + atomTwo.transform.position;
            molecule.transform.position = pos;
            atomTwo.transform.LookAt(atomOne.transform.position);
        }


        //Debug.Log(atomOneReference.name + " " + atomTwoReference.name);

        GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
        cylinder.tag = "Cylinder";
        cylinder.AddComponent<Rigidbody>().useGravity = false;
        cylinder.GetComponent<Collider>().enabled = true;
        cylinder.AddComponent<BreakBond>();

        var dirVector = atomOne.transform.position - atomTwo.transform.position;
        cylinder.transform.position = (atomTwo.transform.position - atomOne.transform.position) / 2.0f + atomOne.transform.position;
        Debug.Log("Atom 1"+atomOne.transform.position+"\n atom2"+atomTwo.transform.position+"\n cylinder"+cylinder.transform.position);
        cylinder.transform.rotation = Quaternion.FromToRotation(Vector3.up, atomTwoTransform.position - atomOneTransform.position);

        atomOneReference.transform.parent = molecule.transform;
        atomTwoReference.transform.parent = molecule.transform;

        cylinder.transform.parent = molecule.transform;

        StartCoroutine(SetAtomPosition(atomOneReference, atomTwoReference, cylinder.transform));

        Vector3 localScale = new Vector3(0.01f, bondLength, 0.01f);
        cylinder.transform.localScale = new Vector3(0.01f, 0.001f, 0.01f);

        StartCoroutine(StartAnimation(cylinder, localScale, bondFormationSpeed, atomOneGameObject, atomTwoGameObject));
        #endregion

        #region setAtomsConsumed
        atomOne.isConsumed = true;
        atomTwo.isConsumed = true;

        atomOne.AddConnection();
        atomTwo.AddConnection();
        #endregion
    }
}

And this method is for adjusting position and few more things 这种方法是用于调整位置和其他一些东西

  private IEnumerator SetAtomPosition(Transform atomOne, Transform atomTwo, Transform cylinder)
{
    while (Vector3.Distance(atomOne.position, atomTwo.position) > atomDistance)
    {
        atomTwo.position = Vector3.MoveTowards(atomTwo.position, atomOne.position, Time.deltaTime * 0.1f);
        yield return 0;
    }

    while (Vector3.Distance(atomOne.position, atomTwo.position) < atomDistance)
    {
        atomTwo.position = Vector3.MoveTowards(atomTwo.position, -atomTwo.forward * 1000f, Time.deltaTime * 0.1f);
        yield return 0;
    }

    cylinder.transform.position = (atomTwo.position - atomOne.position) / 2.0f + atomOne.position;
 //   cylinder.transform.rotation = Quaternion.FromToRotation(Vector3.up, atomTwo.position - atomOne.position);

    #region JoinAtoms

    cylinder.gameObject.AddComponent<FixedJoint>();
    cylinder.gameObject.AddComponent<FixedJoint>();

    var cylinderJoints = cylinder.GetComponents<FixedJoint>();

    cylinderJoints[0].connectedBody = atomOne.GetComponent<Rigidbody>();
    atomOne.GetComponent<Atom>().joint = cylinderJoints[0];
    //cylinderJoints[0].breakForce = breakForce;

    cylinderJoints[1].connectedBody = atomTwo.GetComponent<Rigidbody>();
    atomTwo.GetComponent<Atom>().joint = cylinderJoints[1];
    //cylinderJoints[1].breakForce = breakForce;
    #endregion

    yield return null;
}

Quick and dirty, but i hope you can make something out of it :) 快速又肮脏,但我希望您能从中做出一些贡献:)

The only assumption is that the cylinder is oriented along the z axis (if you dont want that, you need to multiply the quaternion with another rotation), so make it a child of an empty gameobject and rotate it 90° along x. 唯一的假设是圆柱体沿z轴定向 (如果您不希望这样做,则需要将四元数与另一个旋转相乘),因此将其设为空游戏对象的子代并将其沿x旋转90°。

public class Bond : MonoBehaviour {

        public GameObject atom1;
        public GameObject atom2;
        public GameObject bond;

        void Start () {

            Vector3 halfDistance = (atom2.transform.position - atom1.transform.position) * 0.5f;

            bond.transform.position = atom1.transform.position + halfDistance;

            Quaternion bondRotation = Quaternion.LookRotation(halfDistance); 

            bond.transform.rotation = bondRotation;

            bond.transform.localScale = new Vector3(0.5f, 0.5f, halfDistance.magnitude);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM