Пример #1
0
    public void SetData(Vector3 targetPos, float speed, LuaFunction cb, int objID, float fOffset, bool autopathing)
    {
        if (_ObjectComponent == null)
        {
            _ObjectComponent = _Owner.GetComponent <ObjectBehaviour>();
        }

        _TargetPos = targetPos;

        #region 主角自动寻路判断逻辑
        if (_OwnerType == ObjectBehaviour.OBJ_TYPE.HOSTPLAYER)
        {
            if (fOffset > 0.0f && Util.DistanceH(_Owner.transform.position, targetPos) < fOffset)        //检查是否距离过近, 取消寻路,走直线逻辑
            {
                CHostPathFindingInfo.Instance.Clear();
            }
            else
            {
                CalcHostPathFindingInfo();
                SetCameraQuickFollow(autopathing);
            }
        }
        #endregion

        _MoveSpeed   = speed;
        _TargetPos.y = CUnityUtil.GetMapHeight(_TargetPos) + _ObjectComponent.OffsetY;  // 只需要在设置目标点时,计算一次高度
        _DestOffset  = fOffset;
        if (OnFinishCallbackRef != null)
        {
            OnFinishCallbackRef.Release();
        }
        OnFinishCallbackRef = cb;

        _BlockOccurCount = 0;
    }
Пример #2
0
    //找到寻路点上第一个和目标点连通的点
    public bool FindFirstConnectedPoint(Vector3 startPos, Vector3 endPos, Vector3 polyPickExt, float stepSize, out Vector3 selectPoint)
    {
        selectPoint = endPos;

        if (IsConnected(startPos, endPos))
        {
            selectPoint = startPos;
            return(true);
        }

        if (!NavMeshManager.Instance.IsInited)
        {
            return(false);
        }

        float[] tempAllPoints = NavMeshManager.TempAllPoints;

        int     outVertNum = 0;
        Vector3 targetPos  = endPos;

        if (!NavMeshManager.Instance.GetWayPointsAtCurrentMap(startPos, targetPos, polyPickExt, stepSize, 0.1f, tempAllPoints, out outVertNum) || outVertNum <= 0)
        {
            return(false);
        }

        for (int i = 0; i < outVertNum; ++i)
        {
            var vec = new Vector3(tempAllPoints[i * 3], tempAllPoints[i * 3 + 1], tempAllPoints[i * 3 + 2]);
            vec.y = CUnityUtil.GetMapHeight(vec);

            //看是否被阻挡
            RaycastHit hitInfo;
            Vector3    dir    = endPos - startPos;
            float      length = dir.magnitude;
            if (length > 0.1f)
            {
                dir.Normalize();
                if (CUnityUtil.RayCastWithRadius(0, startPos, dir, out hitInfo, length, CUnityUtil.LayerMaskBlockable))
                {
                    break;
                }
            }

            if (NavMeshManager.Instance.IsInited && NavMeshManager.Instance.IsConnected(vec, endPos))
            {
                selectPoint = vec;
                return(true);
            }
        }

        return(false);
    }
Пример #3
0
    public void HandleClick(Vector2 scr_pos, bool can_touch_ground)
    {
        Camera main_camera = Main.Main3DCamera;

        if (main_camera != null)
        {
            Vector3    scr_pos3 = new Vector3(scr_pos.x, scr_pos.y);
            RaycastHit hit_info;
            Ray        ray = main_camera.ScreenPointToRay(scr_pos3);

            int ray_mask;
            if (can_touch_ground)
            {
                ray_mask = CUnityUtil.LayerMaskEntity | CUnityUtil.LayerMaskClickable | CUnityUtil.LayerMaskTerrainBuilding;
            }
            else
            {
                ray_mask = CUnityUtil.LayerMaskHostPlayer;
            }
            if (Physics.Raycast(ray, out hit_info, Mathf.Infinity, ray_mask))
            {
                Collider cd = hit_info.collider;
                if (cd == null)
                {
                    return;
                }

                if (cd.gameObject.layer == CUnityUtil.Layer_Terrain)
                {
                    Vector3 pos = hit_info.point;
                    LuaScriptMgr.Instance.CallLuaOnClickGroundFunc(pos);
                }
                else if (cd.gameObject.layer == CUnityUtil.Layer_Building)
                {
                    Vector3 pos = hit_info.point;
                    pos.y = CUnityUtil.GetMapHeight(pos);
                    LuaScriptMgr.Instance.CallLuaOnClickGroundFunc(pos);
                }
                else if (cd.gameObject.layer != CUnityUtil.Layer_Unblockable)
                {
                    ObjectBehaviour oc = cd.gameObject.GetComponentInParent <ObjectBehaviour>();
                    if (oc != null)
                    {
                        oc.OnClick();
                    }
                }
            }
        }
    }
Пример #4
0
    public bool TickOtherEntity(float dt)
    {
        Vector3 pos = _Owner.position;

        //计算方向,移动
        _MoveDir   = _TargetPos - pos;
        _MoveDir.y = 0;

        float fDistLeft = 0;

        if (!Util.IsValidDir(ref _MoveDir, ref fDistLeft))
        {
            _MoveDir = _Owner.forward;
        }

        float fDeltaMove = _MoveSpeed * dt;
        float fMinDist   = Mathf.Max(fDeltaMove, NEAREST_DIST);

        //判断这次移动的距离是否超过剩余距离,停止
        if (fDistLeft <= fMinDist)
        {
            Vector3 vPos = _TargetPos;      //到达
            vPos.y          = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY;
            _Owner.position = vPos;
            //到达
            RealOnFinish(BEHAVIOR_RETCODE.Success, _MoveDir);
            return(true);
        }

        pos = _Owner.position + fDeltaMove * _MoveDir;
        if (Util.IsNaN(pos))
        {
            return(false);
        }

        pos.y           = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY;
        _Owner.position = pos;

        if (!_ObjectComponent.HasTurnBehavior())              //如果同时有转向,则不设置方向
        {
            if (IsDirChanged)
            {
                TickAdjustDir(_MoveDir);
            }
        }

        return(false);
    }
Пример #5
0
    public bool TickOtherEntity(float dt)
    {
        if (_TargetTrans == null)
        {
            RealOnFinish(BEHAVIOR_RETCODE.Failed, _Owner.forward);
            return(true);
        }

        Vector3 curPos      = _Owner.position;
        Vector3 targetPos   = _TargetTrans.position;
        float   distanceSqr = Util.SquareDistanceH(curPos, targetPos);

        //计算方向,移动
        Vector3 desired = targetPos - _Owner.position;

        desired.y = 0;

        if (!Util.IsValidDir(ref desired))
        {
            desired = _Owner.forward;
        }

        if (distanceSqr < _MaxDistanceSqr && distanceSqr > _MinDistanceSqr)
        {
            if (!_IsLoop)
            {
                RealOnFinish(BEHAVIOR_RETCODE.Success, desired);
                return(true);
            }
            else
            {
                return(false);
            }
        }

        Vector3 pos = _Owner.position + _MoveSpeed * dt * desired;

        if (!_ObjectComponent.HasTurnBehavior()) //如果同时有转向,则不设置方向
        {
            TickAdjustDir(desired);              // desired
        }

        pos.y           = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY;
        _Owner.position = pos;
        return(false);
    }
Пример #6
0
    private static int GetMapHeight(IntPtr L)
    {
        int       count = LuaDLL.lua_gettop(L);
        const int nRet  = 1;

        if ((count == 1 && LuaScriptMgr.CheckTypes(L, 1, typeof(LuaTable))))
        {
            Vector3 pos    = LuaScriptMgr.GetVector3(L, 1);
            float   heigth = CUnityUtil.GetMapHeight(pos);
            LuaScriptMgr.Push(L, heigth);
        }
        else
        {
            LogParamError("GetMapHeight", count);
            LuaScriptMgr.Push(L, 0);
        }
        return(CheckReturnNum(L, count, nRet));
    }
Пример #7
0
    public override bool Tick(float dt)
    {
        if (_ObjectComponent == null)
        {
            _ObjectComponent = _Owner.GetComponent <ObjectBehaviour>();
        }

        // 其他玩家,如果吸附中移动,以移动位置点为准;不移动时,吸附效果为准。
        if (_OwnerType == ObjectBehaviour.OBJ_TYPE.ELSEPLAYER && _ObjectComponent.HasBehavior(BehaviorType.Move))
        {
            return(false);
        }

        var adsorbDir = _AdsorbInfo.Position - _Owner.position;

        adsorbDir.y = 0;
        adsorbDir   = adsorbDir.normalized;

        var moveStep = adsorbDir * _AdsorbInfo.Speed * dt;

        Vector3 newPos;

        if (Util.DistanceH(_AdsorbInfo.Position, _Owner.position) < Util.MagnitudeH(moveStep))
        {
            newPos = _AdsorbInfo.Position;
        }
        else
        {
            newPos = _Owner.position + moveStep;
        }

        newPos.y = CUnityUtil.GetMapHeight(newPos) + _ObjectComponent.OffsetY;
        if (IsValidPositionStrict(newPos) && Util.DistanceH(newPos, _Owner.position) > Util.FloatZero)
        {
            //Debug.LogWarningFormat("{0} {1} Adsorb", Time.frameCount, _Owner.position);
            //Debug.LogWarningFormat("{0} {1} Adsorb", Time.frameCount, newPos);
            _Owner.position = newPos;
        }

        return(false);
    }
Пример #8
0
    //从startPos到endPos, 是否连通,包括obstacle和navmesh
    public bool IsConnected(Vector3 startPos, Vector3 endPos, out Vector3 hitPos)
    {
        hitPos = startPos;

        RaycastHit hitInfo;
        Vector3    dir    = endPos - startPos;
        float      length = dir.magnitude;

        dir.Normalize();

        float ratio0 = 0;

        if (length > 0.1f)
        {
            if (CUnityUtil.RayCastWithRadius(0, startPos, dir, out hitInfo, length, CUnityUtil.LayerMaskBlockable))
            {
                ratio0   = hitInfo.distance / length;
                hitPos   = startPos + (endPos - startPos) * ratio0;
                hitPos.y = CUnityUtil.GetMapHeight(hitPos);
                return(false);
            }
        }

        float ratio1 = 0;

        if (NavMeshManager.Instance.IsInited && !NavMeshManager.Instance.IsConnected(startPos, endPos, ref ratio1))
        {
            if (ratio1 < ratio0)
            {
                hitPos   = startPos + (endPos - startPos) * ratio1;
                hitPos.y = CUnityUtil.GetMapHeight(hitPos);
            }

            return(false);
        }

        return(true);
    }
Пример #9
0
    public bool ShowFileMapRegion(string filename)
    {
        if (_lastFileMapRegionName != filename)
        {
            FileMapRegion newFile = new FileMapRegion();

            try
            {
                byte[] region_data = Util.ReadFile(filename);
                if (!newFile.ReadFromMemory(region_data))
                {
                    HobaDebuger.LogWarning("ShowFileMapRegion, Failed to load " + filename);
                    return(false);
                }
            }
            catch (Exception)
            {
                HobaDebuger.LogWarning("ShowFileMapRegion, Failed to load " + filename);
                return(false);
            }

            _fileMapRegion = newFile;

            _lastFileMapRegionName = filename;
        }

        for (int i = 0; i < _mapRegionGameObjList.Count; ++i)
        {
            GameObject go = _mapRegionGameObjList[i];
            if (go != null)
            {
                GameObject.Destroy(go);
            }
        }
        _mapRegionGameObjList.Clear();
        List <int> Keys = new List <int>(_fileMapRegion.RegionMap.Keys);

        for (int i = 0; i < Keys.Count; ++i)
        {
            FileRegion fileRegion = _fileMapRegion.RegionMap[Keys[i]];

            //
            HashSet <uint> regionGridSet = fileRegion.RegionGridSet;

            List <Vector3> vertices  = new List <Vector3>();
            List <int>     triangles = new List <int>();

            Vector3[] vGrid   = new Vector3[4];
            int       voffset = 0;
            foreach (uint v in regionGridSet)
            {
                if (vertices.Count + 4 > 60000)  //split
                {
                    int        index = _mapRegionGameObjList.Count;
                    GameObject go    = new GameObject(HobaText.Format("MapRegionGameObj_{0}_{1}", Keys[i], index));

                    MeshRenderer meshRenderer = go.AddComponent <MeshRenderer>();
                    meshRenderer.enabled         = true;
                    meshRenderer.name            = HobaText.Format("MapRegionGameObj_{0}_{1}", Keys[i], index);
                    meshRenderer.material.shader = Shader.Find("Legacy Shaders/Bumped Diffuse");
                    meshRenderer.material.color  = GetMeshColor(Keys[i]);
                    CUnityUtil.DisableLightAndShadow(meshRenderer);

                    MeshFilter meshFilter = go.AddComponent <MeshFilter>();
                    meshFilter.sharedMesh           = new Mesh();
                    meshFilter.sharedMesh.name      = HobaText.Format("MeshFilterMesh_{0}_{1}", Keys[i], index);
                    meshFilter.sharedMesh.vertices  = vertices.ToArray();
                    meshFilter.sharedMesh.triangles = triangles.ToArray();

                    _mapRegionGameObjList.Add(go);

                    vertices.Clear();
                    triangles.Clear();
                    voffset = 0;
                }

                uint row = (v & 0xffff0000) >> 16;
                uint col = (v & 0xffff);

                _fileMapRegion.GetGridPositions(row, col, vGrid, 0);

                float fH0 = CUnityUtil.GetMapHeight(vGrid[0]);
                float fH1 = CUnityUtil.GetMapHeight(vGrid[1]);
                float fH2 = CUnityUtil.GetMapHeight(vGrid[2]);
                float fH3 = CUnityUtil.GetMapHeight(vGrid[3]);
//                 if (fH0 == 0.0f || fH1 == 0.0f || fH2 == 0.0f || fH3 == 0.0f)
//                     continue;

                vGrid[0].y = fH0 + 0.1f;
                vGrid[1].y = fH1 + 0.1f;
                vGrid[2].y = fH2 + 0.1f;
                vGrid[3].y = fH3 + 0.1f;

                vertices.Add(vGrid[0]);
                vertices.Add(vGrid[1]);
                vertices.Add(vGrid[2]);
                vertices.Add(vGrid[3]);

                triangles.Add(voffset + 0);
                triangles.Add(voffset + 1);
                triangles.Add(voffset + 2);
                triangles.Add(voffset + 3);
                triangles.Add(voffset + 2);
                triangles.Add(voffset + 1);

                voffset += 4;
            }

            if (vertices.Count > 0)
            {
                int        index = _mapRegionGameObjList.Count;
                GameObject go    = new GameObject(HobaText.Format("MapRegionGameObj_{0}_{1}", Keys[i], index));

                MeshRenderer meshRenderer = go.AddComponent <MeshRenderer>();
                meshRenderer.enabled         = true;
                meshRenderer.name            = HobaText.Format("MapRegionGameObj_{0}_{1}", Keys[i], index);
                meshRenderer.material.shader = Shader.Find("Legacy Shaders/Bumped Diffuse");
                meshRenderer.material.color  = GetMeshColor(Keys[i]);
                CUnityUtil.DisableLightAndShadow(meshRenderer);
                MeshFilter meshFilter = go.AddComponent <MeshFilter>();
                meshFilter.sharedMesh           = new Mesh();
                meshFilter.sharedMesh.name      = HobaText.Format("MeshFilterMesh_{0}_{1}", Keys[i], index);
                meshFilter.sharedMesh.vertices  = vertices.ToArray();
                meshFilter.sharedMesh.triangles = triangles.ToArray();

                _mapRegionGameObjList.Add(go);

                vertices.Clear();
                triangles.Clear();
                voffset = 0;
            }
        }

        return(true);
    }
Пример #10
0
    public override bool Tick(float dt)
    {
        Joystick joystick = Joystick.Instance;

        if (joystick == null)
        {
            return(true);
        }

        _MoveDir = joystick.MoveDir;

        bool bValidDir = Util.IsValidDir(ref _MoveDir);

        if (!bValidDir)
        {
            return(false);
        }

        TickAdjustDir(_MoveDir);

        var curDir = _Owner.forward;

        Vector3 pos = _Owner.position;

        pos.y += 0.6f;


        #region 碰撞检测
        RaycastHit hitInfo;
        if (CUnityUtil.RayCastWithRadius(0, pos, curDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle))
        {
            SyncMoveStampWhenNoProgress();
            return(false);
        }

        if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, pos, curDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC))
        {
            // 修正运动方向
            Vector3 adjustDir;
            {
                Vector3 hitNormal = hitInfo.normal;
                var     v         = Vector3.Cross(hitNormal, curDir);
                adjustDir   = Vector3.Cross(v, hitNormal);
                adjustDir.y = 0;
                adjustDir.Normalize();
            }

            //TickAdjustDir(adjustDir);
            //	朝调整方向trace,如果还有boxcollider则不再寻找新的方向
            if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, pos, adjustDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC))
            {
                SyncMoveStampWhenNoProgress();
                return(false);
            }

            pos = _Owner.position + _MoveSpeed * dt * adjustDir;
            if (!IsValidPositionStrict(pos))
            {
                SyncMoveStampWhenNoProgress();
                return(false);
            }

            pos.y           = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY;
            _Owner.position = pos;
            SyncMoveStampWhenProgress();

            return(false);
        }
        #endregion


        float fTestDist = NavMeshManager.TRACE_EXTEND_DISTANCE;
        if (_MoveSpeed * dt > fTestDist)                //需要测试一个比较近的距离
        {
            Vector3 vTemp = _Owner.position + fTestDist * curDir;
            if (!NavMeshManager.Instance.IsValidPositionStrict(vTemp, false, 0.3f))
            {
                SyncMoveStampWhenNoProgress();
                return(false);
            }
        }

        {
            Vector3 vNearest = pos;
            pos   = _Owner.position + _MoveSpeed * dt * curDir;
            pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY;
            if (NavMeshManager.Instance.GetNearestValidPosition(pos, ref vNearest))
            {
                //取目标点和最近navmesh点的插值,这样可以沿移动方向在navmesh周边滑动
                Vector3 vDelta = pos - vNearest;
                vDelta.y = 0;
                float fLen = vDelta.magnitude;
                if (fLen < 0.01f)
                {
                    pos = vNearest;
                }
                else
                {
                    float fv = Math.Min(fLen, NavMeshManager.TRACE_EXTEND_DISTANCE);                //最大超出navmesh边界0.2 但也不能被服务器拉回 NavMeshManager.IsValidPosition
                    vDelta.Normalize();
                    pos = vNearest + vDelta * fv;
                }
            }
            else
            {
                SyncMoveStampWhenNoProgress();
                return(false);
            }
        }

        if (NavMeshManager.Instance.IsValidPositionStrict(pos, false, NavMeshManager.TRACE_EXTEND_DISTANCE))           //摇杆必须为navmesh有效点,否则会被服务器拉回
        {
            pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY;
            if (!CUnityUtil.IsHeightAccept(pos, _Owner.position))     //高度不合法
            {
                SyncMoveStampWhenNoProgress();
                return(false);
            }

            _Owner.position = pos;
            SyncMoveStampWhenProgress();
        }
        else
        {
            SyncMoveStampWhenNoProgress();
        }

        return(false);
    }
Пример #11
0
    private bool TickHostPlayer3(float dt)
    {
        Vector3 curPos = _Owner.position;

        curPos.y += 0.6f;

        var distLeft = Util.DistanceH(curPos, _TargetPos);

        //到达检查, 如果offset为0,则停在target位置,否则停在当前位置
        if (_DestOffset > 0.0f)
        {
            if (distLeft <= _DestOffset)
            {
                _DestOffset = 0.0f;
                RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward);
                return(true);
            }
        }
        else if (distLeft < NEAREST_DIST)
        {
            Vector3 vPos = _TargetPos;
            vPos.y          = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY;
            _Owner.position = vPos;
            _DestOffset     = 0.0f;
            RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward);
            return(true);
        }

        Vector3 dir = (_TargetPos - curPos);

        dir.y    = 0;
        _MoveDir = dir.normalized;

        var nextPos = Vector3.zero;

        #region 碰撞检测
        RaycastHit hitInfo;
        //检查obstacle碰撞,中断
        if (CUnityUtil.RayCastWithRadius(0, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle))
        {
            RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir);
            return(true);
        }

        if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC))
        {
            Vector3 ahead          = _Owner.position + _Owner.forward * 1.5f;
            Vector3 avoidanceForce = ahead - hitInfo.collider.transform.position;
            avoidanceForce = avoidanceForce.normalized * MAX_AVOID_FORCE;
            Vector3 steering = (_MoveDir * _MoveSpeed + avoidanceForce).normalized;

            nextPos   = _Owner.position + _MoveSpeed * dt * steering;
            nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY;

            if (!IsValidPositionStrict(nextPos))
            {
                RealOnFinish(BEHAVIOR_RETCODE.Blocked, steering);
                return(true);
            }

            steering.y = 0;
            if (!Util.IsValidDir(ref steering))
            {
                steering = _Owner.forward;
            }

            _Owner.position = nextPos;
            if (IsDirChanged)
            {
                TickAdjustDir(steering);
            }

            SyncMoveStamp(dir, false, true, _TargetPos);
            return(false);
        }
        #endregion

        #region 步长是否超过剩余距离
        //判断这次移动的距离是否超过剩余距离,停止
        float fDistMove = _MoveSpeed * dt;
        if (fDistMove >= distLeft)
        {
            Vector3 vPos = _TargetPos;
            vPos.y          = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY;
            _Owner.position = vPos;
            RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward);
            return(true);
        }
        #endregion

        nextPos = curPos + _MoveSpeed * dt * _MoveDir;

        #region NextStepPos NavMesh有效性检查
        Vector3 nextValidPos = Vector3.zero;
        if (NavMeshManager.Instance.GetNearestValidPosition(nextPos, ref nextValidPos, 1.0f))
        {
            Vector3 vDelta = nextPos - nextValidPos;
            vDelta.y = 0;
            float fLen = vDelta.magnitude;
            if (fLen < 0.01f)       //navmesh寻路点
            {
                nextPos = nextValidPos;
            }
            else
            {
                float fv = Math.Min(fLen, NavMeshManager.TRACE_EXTEND_DISTANCE);        //最大可以跨出navmesh范围
                vDelta.Normalize();
                nextPos = nextValidPos + vDelta * fv;
            }

            nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY;

            Vector3 v = nextPos - curPos;
            v.y = 0;
            if (v.sqrMagnitude <= 0.0004f && _MoveSpeed * dt > 0.02f)            //停止不动且和building碰撞, block
            {
                ++_BlockOccurCount;

                if (_BlockOccurCount > 3)
                {
                    _BlockOccurCount = 0;
                    _Owner.position  = nextPos;
                    RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir);
                    return(true);
                }
            }
            else
            {
                _BlockOccurCount = 0;
            }
        }
        else
        {
            nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY;

            _BlockOccurCount = 0;
            RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir);
            return(true);
        }
        #endregion

        _Owner.position = nextPos;

        if (IsDirChanged)
        {
            TickAdjustDir(_MoveDir);
        }

        //避免频繁发送
        SyncMoveStamp(_MoveDir, false, false, _TargetPos);

        return(false);
    }
Пример #12
0
    private bool TickNavigation(float dt)
    {
        Vector3 curPos = _Owner.position;

        //offset判断, 如果offset为0,则停在target位置,否则停在当前位置
        float distSqr = Util.SquareDistanceH(curPos, _TargetPos);

        if (_DestOffset > Util.FloatZero && distSqr <= _DestOffset * _DestOffset)
        {
            _DestOffset = 0.0f;
            RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward);
            return(true);
        }

        if (distSqr < NEAREST_DIST * NEAREST_DIST)
        {
            Vector3 vPos = _TargetPos;
            vPos.y          = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY;
            _Owner.position = vPos;
            _DestOffset     = 0.0f;
            RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward);
            return(true);
        }

        // 吸附中,需要重新计算路线
        if (_ObjectComponent.HasBehavior(BehaviorType.Adsorb))
        {
            if (!CalcHostPathFindingInfo())
            {
                _DestOffset = 0.0f;
                RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir);
                return(true);
            }
        }

        Vector3 vNextPos;
        var     step    = _MoveSpeed * dt;
        int     iPath   = 0;
        var     bArrive = CHostPathFindingInfo.Instance.GetNextNavPosition(step, ref curPos, ref iPath, out vNextPos);

        vNextPos.y = CUnityUtil.GetMapHeight(vNextPos) + _ObjectComponent.OffsetY;

        var facedir = vNextPos - curPos;

        facedir.y = 0;
        if (!Util.IsValidDir(ref facedir))
        {
            facedir = _Owner.forward;
        }

        //寻路到达判断
        if (bArrive)
        {
            _Owner.position = vNextPos;
            _DestOffset     = 0.0f;
            RealOnFinish(BEHAVIOR_RETCODE.Success, facedir);
            return(true);
        }
        _MoveDir = facedir;

        curPos.y += 0.6f;
        RaycastHit hitInfo;

        #region Obstacle碰撞检测
        //检查obstacle碰撞,中断
        if (CUnityUtil.RayCastWithRadius(0, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle))
        {
            _DestOffset = 0.0f;
            RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir);
            return(true);
        }
        #endregion

        if (IgnoreCollisionDetect)           //忽略碰撞
        {
            _Owner.position = vNextPos;

            if (IsDirChanged)
            {
                TickAdjustDir(_MoveDir);
            }

            SyncMoveStamp(_MoveDir, false, false, vNextPos);
            return(false);
        }
        else
        {
            bool bLastCollide = _IsCollidedWithObjects;

            #region NPC碰撞检测
            _IsCollidedWithObjects = CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC);

            if (_IsCollidedWithObjects)
            {
                float dist = Util.SquareDistanceH(curPos, _NavCalcStartPosition);
                if (dist < 1.0f)
                {
                    ++_CollideTryCount;
                }
                else
                {
                    _CollideTryCount = 0;
                }

                if (_CollideTryCount >= 1)
                {
                    _IsCollidedWithObjects = false;
                    _CollideTryCount       = 0;
                }
            }
            #endregion

            if (_IsCollidedWithObjects)
            {
                Vector3 ahead = _Owner.position + _Owner.forward * 1.5f;
                ahead.y = 0;
                Vector3 avoidanceForce = ahead - hitInfo.collider.transform.position;
                avoidanceForce.y = 0;
                avoidanceForce   = avoidanceForce.normalized * MAX_AVOID_FORCE;
                Vector3 steering = (_MoveDir * _MoveSpeed + avoidanceForce).normalized;

                vNextPos = _Owner.position + _MoveSpeed * Math.Max(0.03f, dt) * steering;
                if (!IsValidPositionStrict(vNextPos))                  //尝试不成功则恢复,否则会卡住
                {
                    vNextPos = _Owner.position;
                }
                else
                {
                    vNextPos.y = CUnityUtil.GetMapHeight(vNextPos) + _ObjectComponent.OffsetY;
                }

                _Owner.position = vNextPos;
                if (IsDirChanged)
                {
                    TickAdjustDir(steering);
                }

                SyncMoveStamp(steering, false, true, _TargetPos);
                return(false);
            }
            else
            {
                if (bLastCollide)                   //由碰撞变为不碰撞
                {
                    if (!CalcHostPathFindingInfo()) //以当前点继续寻路
                    {
                        _DestOffset = 0.0f;
                        RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir);
                        return(true);
                    }

                    return(false);
                }
            }

            _Owner.position = vNextPos;
            if (IsDirChanged)
            {
                TickAdjustDir(_MoveDir);
            }

            SyncMoveStamp(_MoveDir, false, false, _TargetPos);

            return(false);
        }
    }
Пример #13
0
    bool TickHostPlayer3(float dt)
    {
        if (_TargetTrans == null)
        {
            RealOnFinish(BEHAVIOR_RETCODE.Failed, _Owner.forward);
            return(true);
        }

        Vector3 curPos      = _Owner.position;
        Vector3 targetPos   = _TargetTrans.position;
        float   distanceSqr = Util.SquareDistanceH(curPos, targetPos);

        Vector3 dir = (targetPos - curPos);

        dir.y = 0;
        Vector3 moveDir = dir.normalized;

        if (distanceSqr < _MaxDistanceSqr && distanceSqr > _MinDistanceSqr)
        {
            if (!_IsLoop)
            {
                RealOnFinish(BEHAVIOR_RETCODE.Success, moveDir);
                return(true);
            }
            else
            {
                return(false);
            }
        }

        curPos.y += 0.6f;
        RaycastHit hitInfo;
        Vector3    nextPos;

        //检查obstacle碰撞,中断
        if (CUnityUtil.RayCastWithRadius(0, curPos, moveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle))
        {
            RealOnFinish(BEHAVIOR_RETCODE.Blocked, moveDir);
            return(true);
        }

        if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, curPos, moveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC))
        {
            Vector3 ahead          = _Owner.position + _Owner.forward * 1.5f;
            Vector3 avoidanceForce = ahead - hitInfo.collider.transform.position;
            avoidanceForce = avoidanceForce.normalized * MAX_AVOID_FORCE;
            Vector3 steering = (moveDir * _MoveSpeed + avoidanceForce).normalized;

            nextPos = _Owner.position + _MoveSpeed * dt * steering;
            if (!IsValidPositionStrict(nextPos))
            {
                RealOnFinish(BEHAVIOR_RETCODE.Blocked, steering);
                return(true);
            }

            dir   = steering;
            dir.y = 0;
            Vector3 vNormalDir;
            if (!Util.IsValidDir(ref dir))
            {
                dir = _Owner.forward;
            }

            nextPos.y       = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY;
            _Owner.position = nextPos;

            SyncMoveStamp(dir, false, true, targetPos);
            return(false);
        }

        //判断这次移动的距离是否超过剩余距离,停止
        float fDistMove = _MoveSpeed * dt;

        if (fDistMove * fDistMove >= distanceSqr)
        {
            targetPos.y     = CUnityUtil.GetMapHeight(targetPos) + _ObjectComponent.OffsetY;
            _Owner.position = targetPos;
            var facedir = targetPos - curPos;
            facedir.y = 0;
            if (!Util.IsValidDir(ref facedir))
            {
                facedir = _Owner.forward;
            }

            RealOnFinish(BEHAVIOR_RETCODE.Success, facedir);
            return(true);
        }

        nextPos   = curPos + _MoveSpeed * dt * moveDir;
        nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY;
        Vector3 nearestPos = new Vector3();

        if (NavMeshManager.Instance.GetNearestValidPosition(nextPos, ref nearestPos, 1.0f))
        {
            Vector3 vDelta = nextPos - nearestPos;
            vDelta.y = 0;
            float fLen = vDelta.magnitude;
            if (fLen < 0.01f)       //navmesh寻路点
            {
                nextPos = nearestPos;
            }
            else
            {
                float fv = Math.Min(fLen, NavMeshManager.TRACE_EXTEND_DISTANCE);        //最大可以跨出navmesh范围
                vDelta.Normalize();
                nextPos = nearestPos + vDelta * fv;
            }

            Vector3 v = nextPos - curPos;
            v.y = 0;
            if (v.sqrMagnitude <= 0.0004f && _MoveSpeed * dt > 0.02f)            //停止不动且和building碰撞, block
            {
                ++_BlockCount;

                if (_BlockCount > 3)
                {
                    _BlockCount = 0;
                    RealOnFinish(BEHAVIOR_RETCODE.Blocked, moveDir);
                    return(true);
                }
            }
            else
            {
                _BlockCount = 0;
            }
        }
        else
        {
            _BlockCount = 0;
            RealOnFinish(BEHAVIOR_RETCODE.Blocked, moveDir);
            return(true);
        }

        nextPos.y       = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY;
        _Owner.position = nextPos;

        TickAdjustDir(moveDir);

        SyncMoveStamp(moveDir, false, false, targetPos);
        return(false);
    }
Пример #14
0
    /*
     * target:目标
     * hud: 发出点
     * ro_ori: 初始角度
     * ro_end:结束角度
     * bullet:发射子物体
     */
    public void BallCurvFly(Vector3 target, GameObject fromObj, GameObject bulletObj, float angle)
    {
        if (fromObj == null || bulletObj == null)
        {
            return;
        }

        Transform from   = fromObj.transform;
        Transform bullet = bulletObj.transform;

        Vector3 fromPos = from.position;

        var length     = Util.DistanceH(target, fromPos);
        var cost       = length / _DevSpeed;;
        var costHSplit = 0.5f;
        var height     = 0f;

        //大于1米的时候 分割抛物线
        if ((target.y - fromPos.y) > 1f)
        {
            height     = length / DEV_LENGTH * _DevHeight / 2 + (target.y - fromPos.y);
            costHSplit = 1 - (height - (target.y - fromPos.y)) / height;
        }
        else
        {
            height = length / DEV_LENGTH * _DevHeight;
        }

        bullet.position = from.position;
        var oriy    = bullet.position.y;
        var destPos = target;

        destPos.y = CUnityUtil.GetMapHeight(destPos);

        if (destPos.y <= CUnityUtil.InvalidHeight)
        {
            destPos.y = oriy;
        }

//         var midPos = from.position + (destPos - from.position) / 2;
//         midPos.y = oriy + height;

        //水平
        _TwList.Add(bullet.DOMoveX(destPos.x, cost).SetEase(Ease.Linear));
        _TwList.Add(bullet.DOMoveZ(destPos.z, cost).SetEase(Ease.Linear));


        //高度
        var tw = bullet.DOMoveY(oriy + height, cost * costHSplit);

        tw.SetEase(Ease.OutQuad);
        _TwList.Add(tw);

        var twLook = bullet.DORotateQuaternion(bullet.rotation * Quaternion.Euler(angle, 0, 0), cost * costHSplit);

        _TwList.Add(twLook);
        twLook.OnComplete(() =>
        {
            _TwList.Add(bullet.DOLookAt(destPos, cost * (1 - costHSplit)));
        });

        tw.OnComplete(() =>
        {
            var tw2 = bullet.DOMoveY(destPos.y, cost * (1 - costHSplit));
            tw2.SetEase(Ease.InQuad);
            _TwList.Add(tw2);
            _IsArrived = true;
        });
    }
Пример #15
0
    public override bool Tick(float dt)
    {
        if (_FinishedTime <= Time.time)
        {
            //Debug.LogFormat("Dash End {0} @{1}", _Owner.position, Time.time);
            RealOnFinish(BEHAVIOR_RETCODE.Success, _Direction);
            return(true);
        }

        // 如果是主角,客户端计算,通知服务器;非主角,完全听服务器的
        if (_OwnerType == ObjectBehaviour.OBJ_TYPE.HOSTPLAYER)
        {
            #region 摇杆控制方向
            if (_CanChangeDir)
            {
                Joystick joystick = Joystick.Instance;
                if (joystick != null && !joystick.MoveDir.IsZero())
                {
                    var destDir  = joystick.MoveDir;
                    var resetDir = _LerpDestDir.IsZero();
                    if (!resetDir)
                    {
                        var angle0 = Vector3.Angle(_LerpDestDir, destDir);
                        if (Vector3.Dot(Vector3.up, Vector3.Cross(_LerpDestDir, destDir)) < 0)
                        {
                            angle0 = 180 - angle0;
                        }

                        resetDir = angle0 > 10;
                    }

                    if (resetDir)
                    {
                        _LerpDestDir = destDir;
                    }
                }

                var newDir = Vector3.Slerp(_Direction, _LerpDestDir, RotationLerpFactor);
                _Direction     = newDir.normalized;
                _Owner.forward = _Direction;

                if (_BlockedEnemyId == 0 && (Time.time - LastSyncTimestamp > 0.1f))
                {
                    var maxDis = _Speed * (_FinishedTime - Time.time);
                    var dis    = Util.GetMaxValidDistance(_Owner.position, _Direction, maxDis);
                    _Destination = _Owner.position + _Direction * dis;
                    // 需要重新同步
                    _ObjectComponent.SyncHostDashInfo(_Owner.position, _Direction, _Destination);
                    LastSyncTimestamp = Time.time;
                }
            }
            #endregion

            Vector3 castpos = _Owner.position;
            castpos.y += 0.6f;      //拔高0.6米进行前方向trace
            RaycastHit hitInfo;

            var raycastStep = _Speed * dt;
            if (raycastStep < 1)
            {
                raycastStep = 1;
            }

            #region 检查Building和obstacle碰撞
            if (CUnityUtil.RayCastWithRadius(0, castpos, _Direction, out hitInfo, raycastStep, CUnityUtil.LayerMaskMovementObstacle))
            {
                if (_CanChangeDir)
                {
                    return(false);
                }
                else
                {
                    RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction);
                    //主角需要通知服务器停住位置
                    _ObjectComponent.SyncHostDashCollideInfo(0, false);
                    return(true);
                }
            }
            #endregion

            var collideWithEntity = CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, castpos, _Direction,
                                                                 out hitInfo, raycastStep, CUnityUtil.LayerMaskEntity);
            #region Entity碰撞
            if (collideWithEntity)
            {
                var collideObj = hitInfo.collider.gameObject.GetComponentInParent <ObjectBehaviour>();
                if (collideObj != null)
                {
                    var collideObjId = collideObj.ID32Bit;

                    if (_CanPierce)
                    {
                        // 技能移动不穿越大型怪物 范导新需求  added by zhouhenan
                        // 20190112 - 增加穿透目标前提,解决穿到怪物肚子中的问题  added by lijian
                        if (_ObjectComponent.OnCollidingHuge(collideObjId))
                        {
                            RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction);
                            _ObjectComponent.SyncHostDashCollideInfo(0, false);
                            return(true);
                        }
                    }
                    else
                    {
                        var collideEntityType = ObjectBehaviour.CollideEntityType.All;
                        if (_OnlyCollideWithSkillTarget)
                        {
                            collideEntityType = ObjectBehaviour.CollideEntityType.OnlyTarget;
                        }
                        else if (_CanChangeDir)
                        {
                            collideEntityType = ObjectBehaviour.CollideEntityType.Enemy;
                        }

                        if (_DashContinue)
                        {
                            // 被同一只怪挡住,原地冲
                            if (_BlockedEnemyId > 0 && _BlockedEnemyId == collideObjId)
                            {
                                return(false);
                            }

                            // 确认是否被目标挡住 如果被挡,需要同步服务器
                            if (_ObjectComponent.OnCollideWithOther(collideObjId, collideEntityType))
                            {
                                _BlockedEnemyId = collideObjId;
                                _ObjectComponent.SyncHostDashCollideInfo(collideObjId, false);
                                return(false);
                            }
                            else if (_BlockedEnemyId > 0)
                            {
                                var maxDis = (_FinishedTime - Time.time) * _Speed;
                                var dis    = Util.GetMaxValidDistance(_Owner.position, _Direction, maxDis);
                                var dst    = _Owner.position + dis * _Direction;
                                _Destination = dst;
                                _ObjectComponent.SyncHostDashCollideInfo(_BlockedEnemyId, true);
                                _BlockedEnemyId = 0;
                            }
                        }
                        else
                        {
                            if (_ObjectComponent.OnCollideWithOther(collideObjId, collideEntityType))
                            {
                                _ObjectComponent.SyncHostDashCollideInfo(collideObjId, false);
                                RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction);
                                return(true);
                            }
                        }
                    }
                }
            }
            #endregion
            else
            {
                if (_BlockedEnemyId > 0)
                {
                    var maxDis = (_FinishedTime - Time.time) * _Speed;
                    var dis    = Util.GetMaxValidDistance(_Owner.position, _Direction, maxDis);
                    var dst    = _Owner.position + dis * _Direction;
                    _Destination = dst;
                    _ObjectComponent.SyncHostDashCollideInfo(_BlockedEnemyId, true);
                    _BlockedEnemyId = 0;
                }
            }
        }
        var pos = _Owner.position + (_Speed * _Direction * dt);
        pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY;

        if (_OwnerType == ObjectBehaviour.OBJ_TYPE.HOSTPLAYER)
        {
            if (!IsValidPositionStrict(pos) || !CUnityUtil.IsHeightAccept(pos, _Owner.position))
            {
                if (_CanChangeDir)
                {
                    return(false);
                }
                else
                {
                    RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction);
                    //主角需要通知服务器停住位置
                    _ObjectComponent.SyncHostDashCollideInfo(0, true);
                    return(true);
                }
            }
        }

        _Owner.position = pos;

        return(false);
    }