/// <summary> /// 更新碰撞和触发 /// </summary> public void UpdateCollisionAndTrigger() { //检测当前所在方块是什么 Vector3 creaturePoint = creature.transform.position; Vector3Int targetBlockPosition = new Vector3Int(Mathf.FloorToInt(creaturePoint.x), Mathf.FloorToInt(creaturePoint.y + 0.5f), Mathf.FloorToInt(creaturePoint.z)); if (targetBlockPosition.y < 0 || targetBlockPosition.y >= WorldCreateHandler.Instance.manager.heightChunk) { return; } WorldCreateHandler.Instance.manager.GetBlockForWorldPosition(targetBlockPosition, out Block targetBlock, out Chunk targetChunk); if (targetBlock != null) { targetBlock.OnCollision(creature.gameObject, targetBlockPosition, DirectionEnum.None); } //检测正前方的碰撞 int layerMask = 1 << LayerInfo.Chunk | 1 << LayerInfo.ChunkTrigger | 1 << LayerInfo.ChunkCollider; if (RayUtil.RayToCast(creaturePoint + Vector3.up * 0.5f, creature.transform.forward, 0.4f, layerMask, out RaycastHit hitForward)) { GetHitPositionAndDirection(hitForward, creature.gameObject, out Vector3Int forwardBlockPosition); WorldCreateHandler.Instance.manager.GetBlockForWorldPosition(forwardBlockPosition, out Block forwardBlock, out Chunk forwardChunk); if (forwardBlock != null) { forwardBlock.OnCollision(creature.gameObject, targetBlockPosition, DirectionEnum.Forward); } } }
/// <summary> /// 检测已摄像头未起点的角色前方的方块 /// </summary> /// <param name="hit"></param> /// <param name="targetBlockPosition"></param> /// <returns></returns> public bool RayToChunkBlock(out RaycastHit hit, out Vector3Int targetPosition) { hit = new RaycastHit(); targetPosition = Vector3Int.zero; //获取摄像头到角色的距离 Vector3 cameraPosition = CameraHandler.Instance.manager.mainCamera.transform.position; ControlForCamera controlForCamera = GameControlHandler.Instance.manager.controlForCamera; float disMax; float disRayBlock = 4; if (controlForCamera.cameraDistance <= 0) { disMax = Vector3.Distance(cameraPosition, player.objFirstLook.transform.position); } else { disMax = Vector3.Distance(cameraPosition, player.objThirdLook.transform.position); } //发射射线检测 RayUtil.RayAllToScreenPointForScreenCenter(disMax + disRayBlock, 1 << LayerInfo.ChunkTrigger | 1 << LayerInfo.ChunkCollider, out RaycastHit[] arrayHit); //如果没有发生碰撞 if (arrayHit == null || arrayHit.Length == 0) { return(false); } bool hasHitData = false; float disTemp = float.MaxValue; for (int i = 0; i < arrayHit.Length; i++) { RaycastHit itemHit = arrayHit[i]; float disHit = Vector3.Distance(itemHit.point, cameraPosition); //如果发射点到碰撞点的距离 小于 发射点到角色的距离 那说明在背后发生了碰撞 则不处理 if (disHit <= disMax) { continue; } else { //选取前方最近的点 if (disHit < disTemp) { disTemp = disHit; hit = itemHit; hasHitData = true; } } } GetHitPositionAndDirection(hit, out targetPosition, out Vector3Int closePosition, out BlockDirectionEnum direction); return(hasHitData); }
/// <summary> /// 处理-检测周围掉落道具 /// </summary> public void HandleForCheckItemCptDrop() { Collider[] colliderArray = RayUtil.RayToSphere(player.transform.position, rangePickUp, 1 << LayerInfo.Items); if (!colliderArray.IsNull()) { for (int i = 0; i < colliderArray.Length; i++) { Collider itemCollider = colliderArray[i]; ItemCptDrop ItemCptDrop = itemCollider.GetComponent <ItemCptDrop>(); //如果是丢掉的道具,并且拾取状态为可拾取 if (ItemCptDrop != null && ItemCptDrop.GetItemCptDropState() == ItemDropStateEnum.DropPick) { ItemCptDrop.PickItem(player.transform, speedPickUp); } } } }
/// <summary> /// 目标检测 /// </summary> public virtual Collider[] TargetCheck(GameObject user, ItemsBean itemsData) { //获取武器伤害 ItemsInfoBean itemsInfo = GetItemsInfo(itemsData.itemId); //获取伤害范围 itemsInfo.GetRangeDamage(out float lengthRangeDamage, out float widthRangeDamage, out float heightRangeDamage); //设置检测范围 Vector3 centerPosition = user.transform.position + user.transform.forward * (lengthRangeDamage / 2f) + new Vector3(0, 1, 0); Vector3 halfEx = new Vector3(lengthRangeDamage, widthRangeDamage, heightRangeDamage); Collider[] targetArray = RayUtil.RayToBox(centerPosition, halfEx, user.transform.rotation, 1 << LayerInfo.Creature); //GameObject objTest = GameObject.CreatePrimitive(PrimitiveType.Cube); //objTest.transform.SetParent(null); //objTest.transform.localScale = halfEx; //objTest.transform.position = centerPosition; //objTest.transform.rotation = user.transform.rotation; return(targetArray); }
public override Vector3 OnHandle(Light light, SurfaceInfo surfaceInfo, RaycastHit hit, Ray ray) { if (surfaceInfo == null) { return(new Vector3(0.0f, 0.0f, 0.0f)); } Vector3 lightResult = new Vector3(0.0f, 0.0f, 0.0f); Vector3 ligthDirection = light.transform.forward; Vector3 normal = hit.normal; Vector3 viewDirection = ray.direction * -1.0f; Vector3 lightNormal = new Vector3(0.0f, 0.0f, 0.0f); //处理环境光 //计算计算点是不是在阴影里面 switch (light.type) { case LightType.Directional: ligthDirection = Vector3.Normalize(-light.transform.forward); if (Vector3.Dot(ligthDirection, hit.normal) > 0) { //在圆内随机采样 Vector3 shadowRayDirection = ligthDirection + Random.onUnitSphere * 0.009f; //Vector3 shadowRayDirection = ligthDirection; if (Physics.Raycast(hit.point, shadowRayDirection, 500)) { return(new Vector3(0.0f, 0.0f, 0.0f)); } //计算高光反射 //lightResult += RayUtil.PhoneLight(ligthDirection, Util.ColorToVector3(light.color), surfaceInfo.specular, light.intensity, normal, viewDirection, surfaceInfo.alpha); //lightResult += RayUtil.BlinnPhong(ligthDirection, Util.ColorToVector3(light.color), surfaceInfo.specular, light.intensity, normal, viewDirection, surfaceInfo.alpha); ////计算漫反射 //lightResult += RayUtil.LambertLight( light.transform.position - hit.point, Util.ColorToVector3(light.color), surfaceInfo.albedo, normal, light.intensity); } break; case LightType.Point: ligthDirection = Vector3.Normalize(hit.point - light.transform.position); break; case LightType.Spot: float distance = Vector3.Distance(hit.point, light.transform.position); ligthDirection = (light.transform.position - hit.point).normalized; float dotDirectionNormal = Vector3.Dot(ligthDirection, hit.normal); if (distance < light.range && dotDirectionNormal > 0.0f) { float dotDirectionLight = Vector3.Dot(ligthDirection, -light.transform.forward); if (dotDirectionLight > (1 - light.spotAngle) / 180f) { if (Physics.Raycast(hit.point, ligthDirection, 500)) { return(new Vector3(0.0f, 0.0f, 0.0f)); } //计算高光反射 //lightResult += RayUtil.PhoneLight(ligthDirection, Util.ColorToVector3(light.color), surfaceInfo.specular, light.intensity, normal, viewDirection, surfaceInfo.alpha); lightResult += RayUtil.BlinnPhong(ligthDirection, Util.ColorToVector3(light.color), surfaceInfo.specular, light.intensity, normal, viewDirection, surfaceInfo.alpha); //计算漫反射 lightResult += RayUtil.LambertLight(light.transform.position - hit.point, Util.ColorToVector3(light.color), surfaceInfo.albedo, normal, light.intensity); } } //聚光灯 break; } return(lightResult); }
public override SurfaceInfo GetSurfaceInfo(Vector2 screenPosition, RaycastHit hit) { SurfaceInfo surfaceInfo = null; if (hit.collider != null) { GameObject gameObject = hit.collider.gameObject; if (gameObject != null) { surfaceInfo = new SurfaceInfo(); surfaceInfo.Init(); Renderer renderer = gameObject.GetComponent <Renderer>(); if (renderer) { Material material = renderer.material; if (material.mainTexture) { Texture2D texture = material.mainTexture as Texture2D; surfaceInfo.emission = Util.ColorToVector3(texture.GetPixelBilinear(hit.textureCoord.x, hit.textureCoord.y)); } else { surfaceInfo.emission = Util.ColorToVector3(material.color); } surfaceInfo.alpha = RayUtil.SmoothnessToAlpha(material.GetFloat("_Glossiness")); surfaceInfo.albedo = material.GetFloat("_Metallic"); surfaceInfo.normal = hit.normal; MeshRenderer meshRenderer = gameObject.GetComponent <MeshRenderer>(); MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>(); if (meshFilter) { Mesh mesh = meshFilter.sharedMesh; Vector3 n; if (GetNormal(hit.point, out n)) { surfaceInfo.normal = n; } else { GetFixedNormal(mesh, ref surfaceInfo.normal, hit.triangleIndex, hit.collider.transform, hit.barycentricCoordinate); PutNormal(hit.point, surfaceInfo.normal); } } if (gameObject.name.Contains("neonsi")) { surfaceInfo.light = new Vector3(1.0f, 0.5f, 0.5f); } } else { if (gameObject.name.Contains("neonsi")) { surfaceInfo.light = new Vector3(0.7f, 0.8f, 0.5f); } Texture2D texture = null; Material material = null; SkinnedMeshRenderer skinnedMeshRenderer = null; SearchTexture(gameObject.transform, ref texture, ref material, ref skinnedMeshRenderer); surfaceInfo.alpha = 0.0f; surfaceInfo.albedo = 0.0f; if (texture && material) { surfaceInfo.emission = Util.ColorToVector3(texture.GetPixelBilinear(hit.textureCoord.x, hit.textureCoord.y)); surfaceInfo.alpha = RayUtil.SmoothnessToAlpha(material.GetFloat("_Glossiness")); surfaceInfo.albedo = material.GetFloat("_Metallic"); } if (skinnedMeshRenderer) { Mesh mesh = skinnedMeshRenderer.sharedMesh; Vector3 n; if (GetNormal(hit.point, out n)) { surfaceInfo.normal = n; } else { GetFixedNormal(mesh, ref surfaceInfo.normal, hit.triangleIndex, hit.collider.transform, hit.barycentricCoordinate); PutNormal(hit.point, surfaceInfo.normal); } } } } } return(surfaceInfo); }