Example #1
0
    /// <summary>
    /// 生成路径的递归函数
    /// </summary>
    /// <param name="lightningSegment">需要划分的线段</param>
    /// <param name="fractalTime">当前递归次数</param>
    /// <param name="maxFractalTime">最大递归次数</param>
    /// <param name="baseAttenuation">基础衰减</param>
    /// <param name="offsetRange">偏离值的范围</param>
    /// <param name="direction">闪电方向</param>
    /// <param name="forward">与闪电方向垂直的一个单位向量</param>
    /// <param name="right">与闪电方向垂直的一个单位向量</param>
    /// <param name="branchChance">生成分支的几率</param>
    private void GetFractcalLightning(LightningSegment lightningSegment, int fractalTime, int maxFractalTime, float baseAttenuation, Vector2 offsetRange, Vector3 direction, Vector3 forward, Vector3 right, float branchChance = 0f)
    {
        if (!lightningSegment.isLeaf() || fractalTime > maxFractalTime)
        {
            return;
        }
        float   zOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
        float   xOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
        Vector3 mid     = lightningSegment.Middle() + xOffset * right + zOffset * forward;

        lightningSegment.LeftChild          = new LightningSegment(lightningSegment.start, mid);
        lightningSegment.LeftChild.fractal  = fractalTime + 1;
        lightningSegment.LeftChild.uv       = lightningSegment.uv - LightningCreator.arrayForUV[lightningSegment.LeftChild.fractal];
        lightningSegment.RightChild         = new LightningSegment(mid, lightningSegment.end);
        lightningSegment.RightChild.fractal = fractalTime + 1;
        lightningSegment.RightChild.uv      = lightningSegment.uv + LightningCreator.arrayForUV[lightningSegment.RightChild.fractal];
        GetFractcalLightning(lightningSegment.LeftChild, fractalTime + 1, maxFractalTime, baseAttenuation, offsetRange, direction, forward, right, branchChance);
        GetFractcalLightning(lightningSegment.RightChild, fractalTime + 1, maxFractalTime, baseAttenuation, offsetRange, direction, forward, right, branchChance);
        if (Random.Range(0f, 1f) < branchChance)
        {
            //制作h形片段
            zOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
            xOffset = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
            float   yOffset   = Mathf.Exp(-baseAttenuation * fractalTime) * Random.Range(offsetRange.x, offsetRange.y);
            Vector3 branchEnd = lightningSegment.Middle() + xOffset * right + zOffset * forward + yOffset * direction;
            lightningSegment.Branch         = new LightningSegment(mid, branchEnd);
            lightningSegment.Branch.fractal = fractalTime + 1;
            lightningSegment.Branch.uv      = lightningSegment.uv + LightningCreator.arrayForUV[lightningSegment.Branch.fractal];
            GetFractcalLightning(lightningSegment.Branch, fractalTime + 1, maxFractalTime, baseAttenuation, offsetRange, direction, forward, right, branchChance);
        }
    }
Example #2
0
 public LightningSegment(Vector3 s, Vector3 e)
 {
     start      = s;
     end        = e;
     LeftChild  = null;
     RightChild = null;
     Branch     = null;
     uv         = 0.5f;
     fractal    = 1;
 }
Example #3
0
    public void CreateLightning(Vector3 start, Vector3 end)
    {
        if (start == end)
        {
            return;
        }
        float Length = (end - start).magnitude;

        trunk = new LightningSegment(start, end);
        Vector2 OffsetRange = Length * new Vector2(MinOffset, MaxOffset);
        //计算一个正交基
        Vector3 LightningDir = end - start;
        //找到不为0的一个分量
        Vector3 forward;

        if (LightningDir.x != 0)
        {
            forward = new Vector3(-(LightningDir.y + LightningDir.z) / LightningDir.x, 1, 1);
        }
        else if (LightningDir.y != 0)
        {
            forward = new Vector3(1, -(LightningDir.x + LightningDir.z) / LightningDir.y, 1);
        }
        else if (LightningDir.z != 0)
        {
            forward = new Vector3(1, 1, -(LightningDir.x + LightningDir.y) / LightningDir.z);
        }
        else
        {
            return;
        }
        forward.Normalize();
        Vector3 right = Vector3.Cross(LightningDir, forward);

        right.Normalize();
        LightningDir.Normalize();
        GetFractcalLightning(trunk, 1, FractalTime, BaseAttenuation, OffsetRange, LightningDir, forward, right, BranchChance);
        Mesh mesh = MakeMesh(trunk, Radius, RadiusAttenuation, Observer.position, Length);
        //创造新的闪电
        GameObject go = Instantiate(templet) as GameObject;

        go.GetComponent <MeshFilter>().mesh = mesh;
        go.transform.position = Vector3.zero;
        go.transform.parent   = transform;
        go.SetActive(true);
    }
Example #4
0
    private Mesh MakeMesh(LightningSegment lightningSegment, float radius, float attenuation, Vector3 obPos, float length)
    {
        Mesh           mesh      = new Mesh();
        List <Vector3> vertices  = new List <Vector3>();
        List <int>     triangles = new List <int>();
        List <Vector2> uvs       = new List <Vector2>();
        int            idx       = 0;

        SegmentToMesh(lightningSegment, vertices, triangles, uvs, obPos, radius, attenuation, ref idx);
        mesh.SetVertices(vertices);
        mesh.triangles = triangles.ToArray();
        mesh.SetUVs(0, uvs);
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        mesh.RecalculateTangents();
        return(mesh);
    }
Example #5
0
 /// <summary>
 /// 填充Mesh的递归函数
 /// </summary>
 /// <param name="lightningSegment">需要生成Mesh的线段</param>
 /// <param name="vertices"></param>
 /// <param name="triangle"></param>
 /// <param name="uv"></param>
 /// <param name="obPos">摄像机位置</param>
 /// <param name="radius">当前的闪电粗细</param>
 /// <param name="attenuation">分支闪电的衰减程度</param>
 /// <param name="idx">顶点序号</param>
 private void SegmentToMesh(LightningSegment lightningSegment, List <Vector3> vertices, List <int> triangle,
                            List <Vector2> uv, Vector3 obPos, float radius, float attenuation, ref int idx)
 {
     if (lightningSegment.isLeaf())
     {
         Vector3 zMid    = lightningSegment.Middle();
         Vector3 zNormal = Vector3.Cross(zMid - obPos, lightningSegment.end - lightningSegment.start).normalized;
         var     finalR  = radius * attenuation;
         if (lightningSegment.Branch == null)
         {
             //Z型片段的Mesh生成
             vertices.Add(lightningSegment.start + finalR * zNormal);
             vertices.Add(lightningSegment.start - finalR * zNormal);
             vertices.Add(lightningSegment.end + finalR * zNormal);
             vertices.Add(lightningSegment.end - finalR * zNormal);
             triangle.Add(idx + 1);
             triangle.Add(idx);
             triangle.Add(idx + 2);
             triangle.Add(idx + 1);
             triangle.Add(idx + 2);
             triangle.Add(idx + 3);
             uv.Add(new Vector2(1, lightningSegment.uv));
             uv.Add(new Vector2(0, lightningSegment.uv));
             uv.Add(new Vector2(1, lightningSegment.uv));
             uv.Add(new Vector2(0, lightningSegment.uv));
             idx += 4;
         }
     }
     else
     {
         SegmentToMesh(lightningSegment.LeftChild, vertices, triangle, uv, obPos, radius, attenuation, ref idx);
         SegmentToMesh(lightningSegment.RightChild, vertices, triangle, uv, obPos, radius, attenuation, ref idx);
         if (lightningSegment.Branch != null)
         {
             SegmentToMesh(lightningSegment.Branch, vertices, triangle, uv, obPos, radius * attenuation, attenuation, ref idx);
         }
     }
 }
Example #6
0
    // Update is called once per frame
    void Update()
    {
        bool forward, back, left, right;

        forward = Input.GetKey(KeyCode.W);
        back    = Input.GetKey(KeyCode.S);
        left    = Input.GetKey(KeyCode.A);
        right   = Input.GetKey(KeyCode.D);

        Vector3 camRight   = Vector3.Cross(new Vector3(0, 1, 0), curentCamera.transform.forward).normalized;
        Vector3 camForward = -Vector3.Cross(new Vector3(0, 1, 0), camRight).normalized;

        Vector2 localClick = new Vector2();
        Camera  cam        = GameDirector.Director.currentCamera.GetComponent <Camera>();

        if (RectTransformUtility.RectangleContainsScreenPoint(Q, Input.mousePosition) && Input.GetMouseButtonDown(0))
        {
            Debug.Log("Q skill");
            foreach (GameObject enemy in GameDirector.Director.enemiesSpawned)
            {
                enemy.GetComponent <SlimeMovement>().stun(this.gameObject);
                LightningSegment.spawnLightningChain(this.gameObject, enemy, lightningLine);
                //Debug.Break();
            }
        }
        else if (RectTransformUtility.RectangleContainsScreenPoint(W, Input.mousePosition) && Input.GetMouseButtonDown(0))
        {
            Debug.Log("W skill");
        }
        else if (RectTransformUtility.RectangleContainsScreenPoint(E, Input.mousePosition) && Input.GetMouseButtonDown(0))
        {
            Debug.Log("E skill");
        }
        else if (RectTransformUtility.RectangleContainsScreenPoint(R, Input.mousePosition) && Input.GetMouseButtonDown(0))
        {
            Debug.Log("R skill");
            Instantiate(spookPrefab, this.transform);
            GameDirector.Director.mainLight.GetComponent <Light>().intensity = 0;
            Invoke("lightBackOn", 10);
        }
        else
        {
            RaycastHit retVal = new RaycastHit();
            Physics.Raycast(curentCamera.GetComponent <Camera>().ScreenPointToRay(Input.mousePosition), out retVal);
            Vector3       wantDir      = new Vector3();
            SlimeMovement attackTarget = null;

            if (retVal.collider != null)
            {
                SlimeMovement enemyHit = retVal.transform.gameObject.GetComponent <SlimeMovement>();
                if (enemyHit != null)
                {
                    wantDir = enemyHit.transform.position - this.transform.position;
                    if ((enemyHit.transform.position - this.transform.position).magnitude < attackRange && Input.GetMouseButtonDown(0))
                    {
                        attackTarget = enemyHit;
                    }
                }
                else
                {
                    wantDir = retVal.point + new Vector3(0, this.transform.position.y, 0) - this.transform.position;
                }
                wantDir = wantDir.normalized * moveSpeed;

                /*if (wantDir.magnitude > moveSpeed)
                 * {
                 *  wantDir = wantDir.normalized * moveSpeed;
                 * }
                 * else if (wantDir.magnitude < moveSpeed / 2)
                 * {
                 *  wantDir = wantDir.normalized * moveSpeed/2;
                 * }*/
                Debug.DrawRay(this.transform.position, wantDir, Color.cyan);
                if (Time.time - moveTime > 0 && Input.GetMouseButtonDown(0))
                {
                    float jump = Random.value > .7 ? moveSpeed : 0;
                    phys.velocity = new Vector3(wantDir.x, phys.velocity.y + jump, wantDir.z);
                    moveTime      = Time.time + moveDownTime;
                    //Debug.Log("moved!");
                }
            }

            if (attackTarget && Time.time - nextAttackTime > 0)
            {
                energy        += attack(attackTarget);
                nextAttackTime = Time.time + attackCoolDown;
            }
        }


        /*Vector3 newMove = new Vector3();
         * newMove.y = phys.velocity.y;
         * if (forward) newMove += moveSpeed*camForward;
         * if (back) newMove += -moveSpeed * camForward;
         * if (left) newMove += -moveSpeed * camRight;
         * if (right) newMove += moveSpeed * camRight;
         */

        //Debug.DrawRay(this.transform.position, camRight, Color.green);
        //Debug.DrawRay(this.transform.position, camForward, Color.red);



        //phys.velocity = newMove;
    }
Example #7
0
 private float attack(SlimeMovement enemy)
 {
     LightningSegment.spawnLightningChain(this.gameObject, enemy.gameObject, lightningLine);
     enemy.damage(1);
     return(1);
 }