内含一些对象池的代码类

30 篇文章 0 订阅
24 篇文章 1 订阅
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using Random = UnityEngine.Random;

public class LotteryDemo : MonoBehaviour
{
    public static LotteryDemo instance;

    public static int[] textArray;
    public static Dictionary<int, Texture2D> textMap = new Dictionary<int, Texture2D>();

    public static int[] DebristextArray;
    public static Dictionary<int, Texture2D> DebristextMap = new Dictionary<int, Texture2D>();

    public Camera worldCamera;
    public float forceFactor = 1;
    public Action del = null;
     
    public bool slideMode = false; //默认是点击模式(单抽),滑动模式请打开(十连抽)
    public float defaultVelocity = 50;
    public float slideVelocity = 10;
    public float minSlideDistance = 100;
    bool isForbiden = true;

    public float inAreaRadius = 100; //最小影响半径
    public int outAreaRadius = 1500; //滑动时,最大影响半径,在这个半径内线性衰减到0

    public int minDragSpeed = 100;
    public int maxDragSpeed = 1000;
    public int dragSpeedFactor = 100;

    public List<int> heroIds; //抽卡结果,如果只有一个值,则表示为单抽
    public List<int> qualitys;//抽卡的品质
    public List<bool> existing;//已经拥有的卡片
    private int waitingCount; //还需要等待几个才能完成

    public Action startCb;
    public Action overCb;
    public Action<int> selectSummonHero;
    Vector3 startTouchPos;//开始拖动的屏幕位置
    float startTouchTime; //开始拖动的时间
    private bool IsSummoned = false;
    CardCtr[] cards;
    public float changeDebrisDelay = 0.5f;
    private GameObject clickEff;
    private GameObject clickEff2;


    private static Queue<GameObject> usedBall = new Queue<GameObject>();//使用过的质量球

    private static Dictionary<int, Queue<GameObject>> qualityBallPool = new Dictionary<int, Queue<GameObject>>();//质量球对象池
    private static Dictionary<int, GameObject> qualityBallGO = new Dictionary<int, GameObject>();//质量球类型

    private static Queue<GameObject> changeDebrisPool = new Queue<GameObject>(); //转换碎片对象池
    private static GameObject changeDebriEff;// = new GameObject();//转换碎片特效
    private static Queue<GameObject> usedDebrisPool = new Queue<GameObject>();//使用过的碎片特效


    private void InitEffect()
    {
        qualityBallPool.Add(1, new Queue<GameObject>());//green
        qualityBallPool.Add(2, new Queue<GameObject>());//blue
        qualityBallPool.Add(3, new Queue<GameObject>());//purple
        qualityBallPool.Add(4, new Queue<GameObject>());//yellow

        qualityBallGO.Add(1, Resources.Load("UIEffects/Eff_GJUI_chouka_GreenLoop") as GameObject);//green
        qualityBallGO.Add(2, Resources.Load("UIEffects/Eff_GJUI_chouka_BlueLoop") as GameObject);//blue
        qualityBallGO.Add(3, Resources.Load("UIEffects/Eff_GJUI_chouka_PurpleLoop") as GameObject);//purple
        qualityBallGO.Add(4, Resources.Load("UIEffects/Eff_GJUI_chouka_YellowLoop") as GameObject);//yellow
    }


    void Start(){
        instance = this;
        isForbiden = true;
        cards = GetComponentsInChildren<CardCtr>();
        LoadHeadImage();
        InitEffect();

        var cameraData = worldCamera.GetUniversalAdditionalCameraData();
        cameraData.renderType = CameraRenderType.Overlay;
        clickEff = Instantiate(Resources.Load("UIEffects/Eff_GJUI_chouka_YellowBOOM")) as GameObject;//Eff_GJUI_chouka_YellowBOOM
        clickEff.transform.parent = this.transform;
        clickEff.SetActive(false);

        clickEff2 = Instantiate(Resources.Load("UIEffects/Eff_GJUI_chouka_huadong")) as GameObject;
        clickEff2.name = "zheshiyigedianji";
        clickEff2.transform.parent = this.transform;
        clickEff2.SetActive(false);

        changeDebriEff = Resources.Load("UIEffects/Eff_GJUI_suipianzhuanhua") as GameObject;
        changeDebriEff.SetActive(false);
    }

    public void SetBoolFalse()
    {
        this.IsSummoned = false;
    }



    #region 质量球对象池


    /// <summary>
    /// 根据type得到一个球
    /// </summary>
    public static void GetOneQualityBallByType(int qualityType, Transform t)
    {
        //因为代码会遗留上次抽卡的质量值,所以抽卡结束后质量值设置成99,如果质量值是99 则不得到球,
        if (qualityType == 99 || qualityType == 0)
        {
            return;
        }

        if (qualityBallPool[qualityType].Count <= 0)
        {
            GameObject go = Instantiate(qualityBallGO[qualityType], t);
            go.name = qualityType.ToString();
            go.transform.position = t.position - new Vector3(0, 0, 0.05f);
            go.transform.localScale = new Vector3(1.22f, 1.22f, 1.22f);
            usedBall.Enqueue(go);
        }
        else
        {
            GameObject go = qualityBallPool[qualityType].Dequeue();
            go.transform.position = t.position - new Vector3(0, 0, 0.05f);
            go.transform.localScale = new Vector3(1.22f, 1.22f, 1.22f);
            usedBall.Enqueue(go);
        }

    }
    /// <summary>
    /// 移除一个球到对象池
    /// </summary>
    public static void RemoveOneQualityBall(GameObject go)
    {
        go.transform.position = new Vector3(9999, 0, 0);
        qualityBallPool[Int32.Parse(go.name)].Enqueue(go);

    }

    /// <summary>
    /// 移除所有的球到对象池
    /// </summary>
    public void ReMoveAllQualityBalls()
    {
        int count = usedBall.Count;
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                GameObject go = usedBall.Dequeue();
                RemoveOneQualityBall(go);
            }

        }


    }
    /// <summary>
    /// 得到一个特效
    /// </summary>
    public void GetOneDebriEff(Transform t)
    {
        

        if (changeDebrisPool.Count <= 0)
        {
            GameObject go = Instantiate(changeDebriEff, t);
            go.SetActive(true);
            //go.name = qualityType.ToString();
            go.transform.position = t.position- new Vector3(0, 0, 0.05f);
            go.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
            usedDebrisPool.Enqueue(go);
        }
        else
        {
            GameObject go = changeDebrisPool.Dequeue();
            go.SetActive(true);
            go.transform.position = t.position- new Vector3(0, 0, 0.05f);
            go.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
            usedDebrisPool.Enqueue(go);
        }

    }
    /// <summary>
    /// 移除一个球到对象池
    /// </summary>
    public void RemoveOneDebri(GameObject go)
    {
        go.SetActive(false);
        go.transform.position = new Vector3(9999, 0, 0);
        changeDebrisPool.Enqueue(go);

    }

    /// <summary>
    /// 移除所有的球到对象池
    /// </summary>
    public void ReMoveAllDebris()
    {
        int count = usedDebrisPool.Count;
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                GameObject go = usedDebrisPool.Dequeue();
                RemoveOneDebri(go);
            }

        }


    }


    #endregion

    public void LoadHeadImage()
    {
        

        Texture2D[] images = Resources.LoadAll<Texture2D>("UIImage/Summon/card");
        textArray = new int[images.Length];
        for (int i = 0; i < images.Length; i++)
        {
            int id = int.Parse(images[i].name);
            textArray[i] = id;
            textMap[id] = images[i];
        }

        Texture2D[] Debrisimages = Resources.LoadAll<Texture2D>("UIImage/Summon/cardDebris");
        DebristextArray = new int[Debrisimages.Length];
        for (int i = 0; i < Debrisimages.Length; i++)
        {
            int id = int.Parse(Debrisimages[i].name);
            DebristextArray[i] = id;
            DebristextMap[id] = Debrisimages[i];
        }

    }

    public void initCardAction(Action one,Action ten){

    }

    void ApplyHitForce(ref RaycastHit hitInfo, Vector3 forcePoint)
    {   
        
        clickEff.SetActive(true);
        clickEff.transform.position = forcePoint;

        GameObject go = hitInfo.collider.gameObject;
        //Vector3 screenPos = worldCamera.WorldToScreenPoint(go.transform.position);
        float deltaX = forcePoint.x - go.transform.position.x;
        float deltaY = forcePoint.y - go.transform.position.y;
        Vector3 rotation = new Vector3(deltaX ,deltaY,0);
        float weight =  Mathf.Pow(1 + rotation.magnitude,2);
        float N = weight * forceFactor * 10;
        CardCtr card = go.GetComponentInChildren<CardCtr>();
        Debug.LogError(N);
        waitingCount = 1;
        card.setTarget(N, rotation, heroIds[0],qualitys[0], existing[0]);
        heroIds = null;
    }

    public void setCards(List<int> list, List<int> Qualitys,List<bool> existing, Action startFun,Action overFunc,Action<int> SelectSummonHero){
        this.startCb = startFun;
        this.overCb = overFunc;
        this.selectSummonHero = SelectSummonHero;
        this.isForbiden = false;
        this.slideMode = list.Count >= 10 ;
        this.heroIds = list;
        this.qualitys = Qualitys;
        this.existing = existing;
        ResetAll();

        this.IsSummoned = false;

    }

    float GetAreaForce(float distance)
    {
        if (distance > outAreaRadius)
        {
            distance = outAreaRadius;
        }
        if (distance < inAreaRadius)
            return 1;
        float ret = (outAreaRadius - distance) / (outAreaRadius - inAreaRadius);
        return Mathf.Max(0.1f, ret * ret);
    }

    float GetSpeedFactor(float speed)
    {
        if (speed > maxDragSpeed)
        {
            return dragSpeedFactor;
        }
        if (speed < minDragSpeed)
        {
            speed = minDragSpeed;
        }

        float result = (outAreaRadius - speed) / (outAreaRadius - inAreaRadius);
        return Mathf.Max(0.1f,result*result)* dragSpeedFactor;
    }    

    public void ResetAll()
    {
        CardCtr[] arr = gameObject.GetComponentsInChildren<CardCtr>();
        for (int i = 0; i < arr.Length; i++)
        {
            arr[i].ResetRotation();
            arr[i].HeroId = 0;
        }

        ReMoveAllQualityBalls();
        ReMoveAllDebris();
        SetDebriFalse();

    }
    /// <summary>
    /// 设置成false防止下次全亮
    /// </summary>
    public void SetDebriFalse()
    {
        foreach (CardCtr item in cards)
        {
            item.isDebris = false;
        }
    }



    public void OneCardOver()
    {
        waitingCount--;
        if (waitingCount == 0)
        {
            this.overCb();
            clickEff.SetActive(false);
            clickEff2.SetActive(false);
            this.IsSummoned = true;
        }
    }

    // Update is called once per frame
    void Update()
    {
        

        if (Input.GetMouseButtonDown(0)&&IsSummoned)
        {
            Vector3 hitPos = Input.mousePosition;
            var ray = worldCamera.ScreenPointToRay(hitPos);
            RaycastHit hitInfo;
            if (Physics.Raycast(ray, out hitInfo, 100, 1 << LayerMask.NameToLayer("Default")))
            {
                CardCtr cc = hitInfo.transform.GetComponent<CardCtr>();
                selectSummonHero(cc.HeroId);
                
                //print(hitInfo.collider.gameObject.name);
            }
        }


        if (this.isForbiden){
            return;
        }
        bool leftDown = Input.GetMouseButtonDown(0);
        bool leftUp = Input.GetMouseButtonUp(0);
        bool leftHold = Input.GetMouseButton(0);

        Vector3 pos = Input.mousePosition;
        if (Input.touchSupported)
        {
            if (Input.touchCount > 0){
                leftDown = (Input.GetTouch(0).phase == TouchPhase.Began);
                leftUp = (Input.GetTouch(0).phase == TouchPhase.Ended);
                leftHold = (Input.GetTouch(0).phase == TouchPhase.Moved);
            }
        }

        if (leftDown)
        {
            clickEff2.SetActive(true);
            startTouchPos = pos;
            startTouchTime = Time.time;
            return;    
        }

        if (!slideMode) {
            if (leftUp && heroIds!=null)
            {
                Vector3 hitPos = pos;
                var ray = worldCamera.ScreenPointToRay(hitPos);
                RaycastHit hitInfo;
                if (Physics.Raycast(ray, out hitInfo, 100, 1 << LayerMask.NameToLayer("Default")))
                {
                    ApplyHitForce(ref hitInfo, hitInfo.point);
                }
            }
        }
        else
        {
            Vector3 curPos = pos;


            if (leftHold) //拖动中
            {
                Vector3 point = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 2f);
                clickEff2.transform.position = worldCamera.ScreenToWorldPoint(point);


                Vector3 deltaPos = curPos - startTouchPos;
                if (deltaPos.x == 0 && deltaPos.y == 0)
                {
                    return;
                }

                Vector3 rotation = new Vector2(deltaPos.y, -deltaPos.x);
                for (int i = 0; i < cards.Length; i++)
                {
                    CardCtr card = cards[i];
                    GameObject go = cards[i].gameObject;
                    Vector3 screen_go = worldCamera.WorldToScreenPoint(go.transform.position);
                    float dist = (screen_go - curPos).magnitude;
                    float areaForce = GetAreaForce(dist);
                    float factor = areaForce * 90 * Mathf.Min(1,(rotation.magnitude/outAreaRadius*2));
                    card.Drag(factor, rotation);
                }
            }
            else if (leftUp) // 释放
            {
                Vector3 deltaPos = curPos - startTouchPos;
                float timeDelta = Time.time - startTouchTime;
                float speed = GetSpeedFactor(deltaPos.magnitude / timeDelta);
                if(Math.Sqrt(deltaPos.sqrMagnitude) < minSlideDistance){
                    ResetAll();
                }else{
                    this.isForbiden = true;
                    if(this.startCb != null){
                        this.startCb();
                    }
                    
                    Vector3 rotation =new Vector2(deltaPos.y,-deltaPos.x);
                    for(int i=0;i<cards.Length;i++){
                        CardCtr card = cards[i];
                        GameObject go = cards[i].gameObject;
                        Vector3 screen_go = worldCamera.WorldToScreenPoint(go.transform.position);
                        float dist = GetAreaForce((screen_go - curPos).magnitude) ;
                        dist += GetAreaForce((screen_go - startTouchPos).magnitude);
                        //float factor = dist * forceFactor * rotation.magnitude;
                        float factor = dist * forceFactor * speed;
                        //Debug.LogError(factor);
                        card.setTarget(factor, rotation,heroIds.Count >i? heroIds[i]:0,qualitys[i], existing[i]);
                        waitingCount = 10;
                    }
                }
            }
        }
    }

    public void Dispose()
    {
        usedBall.Clear();
        qualityBallPool.Clear();
        qualityBallGO.Clear();
    }
    public void ChangeDebris()
    {
        StartCoroutine(changeDebris());
    }

    IEnumerator changeDebris()
    {
        yield return new WaitForSeconds(changeDebrisDelay);
        foreach (CardCtr item in cards)
        {
            bool bl = item.ChangeDebris();

            if (bl)
            {
                //创建一个特效
                GetOneDebriEff(item.gameObject.transform);
            }


        }
    }




}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值