标签:间隔 不同的 sha 点击 性能 lin 比较 first bool
一进游戏把鼠标指针切换成想要的形状:
File-->Build settings,最下面有个player setting,在右侧属性中有个Default Cursor,拖动图片到那里即可
镜头很远观看物体时有雾的效果:
edit-->render setting,勾选fog,调整浓度
场景切换白色渐变效果做法:
在NGUI中创建一个simple texture,Texture选择纯白色,选中它,右键tween-->alpha,from为1,to为0由于进入游戏需要一段时间,Start Delay设为1秒
过一会要显示游戏名字,我们把标题的alpha先设为0,添加alpha的tween,让它一会显示出来,ping pong播放
给按任意键开始游戏这个按钮添加脚本
public class PressAnyKey : MonoBehaviour { //按任意键开始是否按下 private bool start = false; private GameObject button; private void Start() { button = transform.parent.Find("ButtonContainer").gameObject; } void Update () { if (start==false) { if (Input.anyKey) { showButton(); } } } //显示新游戏和载入游戏 private void showButton() { button.SetActive(true); this.gameObject.SetActive(false); start = true; } }这里注意的是
transform.parent.Find("ButtonContainer").gameObject;拿到按钮的Gameobject要注意层级关系transform.parent.find
犯的错误; public GameObject[] characterPrefabs;将prefab中的Gameobject拖动到里面,那么请问还需要在代码中添加这段代码吗
characterPrefabs=new GameObject[characterPrefabs.length];
答:不能再添加这句话,否则报空指针
如果在最上面 private GameObject[] characterObjects;那么还需要new来初始化吗?
答,需要
按钮按下调用脚本注意要把调用的方法设成public才能调用
在写脚步时候遇到的问题
public GameObject[] characterPrefabs; private int nowIndex = 0; private GameObject[] characterObjects; private void Start() { int length = characterPrefabs.Length; characterObjects = new GameObject[length]; for (int i= 0; i< characterPrefabs.Length; i++) { characterObjects[i]= Instantiate(characterPrefabs[i], characterPrefabs[i].transform.position, characterPrefabs[i].transform.rotation) ; } UpdateCharacterShow(); } //显示当前的角色,隐藏其他职业的角色显示 void UpdateCharacterShow() { foreach (GameObject go in characterObjects) { go.SetActive(false); } characterObjects[nowIndex].SetActive(true); }这里characterPrefab是把人物模型从prefab中拖到数组中,但是如果我把updateCharacterShow方法中的characterObjects全部改成characterPrefabs程序不能运行,我觉得可能是characterObjects给new出来了,开辟了内存空间造成的,characterPrefabs只是声明了而已
在c#中能否在一个常量前面加static?
答,不能,
在c#中能否在一个变量前面加static?
答,可以,
我们一般这样声明一个常量:
如果这样声明一个常量的话,在另一个目录里面的脚本也可以调用该脚本的常量
但是java中好像就可以
public static final double PI=3.14159265358979323864;
鼠标点击地面产生的指针特效:
public class PlayerDir : MonoBehaviour { //鼠标左键单击的特效拖过来 public GameObject effect_click_prefab; void Update () { if (Input.GetMouseButtonDown(0)) { Ray ray= Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo; //用一个bool来看有没有射线碰撞,如果有,而且碰撞到地面的话就显示鼠标左键的特效 bool isCollider = Physics.Raycast(ray,out hitInfo); if(isCollider&&hitInfo.collider.tag==Tags.ground){ ShowClickEffect(hitInfo.point); } } }
//如果鼠标点了一下,就实例化一个单击的特效 void ShowClickEffect(Vector3 hitPoint) { Instantiate(effect_click_prefab,hitPoint,Quaternion.identity); } }
如果鼠标左键的特效显示不完整就把hitPoint的y轴坐标加0.1f即可,
如果点击这个圆盘由于他的高度比较高,让鼠标特效显示不出来,给圆盘添加mesh collider,tags改成ground即可最后我们让鼠标左键即使按住也可以实时改变目标的朝向:
public class PlayerDir : MonoBehaviour { //鼠标左键单击的特效 public GameObject effect_click_prefab; //是否面向鼠标点击的位置 private bool isLookAt=false; void Update () { if (Input.GetMouseButtonDown(0)) { Ray ray= Camera.main.ScreenPointToRay(Input.mousePosition); //用一个bool来看有没有射线碰撞,如果有,而且碰撞到地面的话就显示鼠标左键的特效 RaycastHit hitInfo; bool isCollider = Physics.Raycast(ray,out hitInfo); if(isCollider&&hitInfo.collider.tag==Tags.ground){ ShowClickEffect(hitInfo.point); isLookAt = true; } } else if (Input.GetMouseButtonUp(0)) { isLookAt = false; } if (isLookAt) { CharacterLookAtClick(); } } //猪脚面向鼠标 void CharacterLookAtClick() { //这里有个非常值得注意的地方,为什么不直接把上面的hitInfo传过来拿到目标点而是还要在函数里再做射线, //因为GetMouseButtonDown只要按下只返回一次那里做的射线是按下那一刹那做出的目标点,
//如果按住鼠标需要通过Input.GetMouseButton来实时返回结果 //所以鼠标一直按住isLookAt是true,那么在这个函数再做一次射线检测才行 RaycastHit hitInfo; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); bool isCollider = Physics.Raycast(ray, out hitInfo); if (isCollider && hitInfo.collider.tag == Tags.ground) { transform.LookAt(hitInfo.point); } } //如果鼠标点了一下,就实例化一个单击的特效 void ShowClickEffect(Vector3 hitPoint) { Instantiate(effect_click_prefab,hitPoint,Quaternion.identity); } }
当MonoBehaviour启用时,其Update在每一帧被调用。
FixedUpdate 固定更新
当MonoBehaviour启用时,其 FixedUpdate在每一帧被调用。处理Rigidbody时,需要用FixedUpdate代替Update。例如:给刚体加一个作用力时,你必须应用作用力在FixedUpdate里的固定帧,而不是Update中的帧。(两者帧长不同)
LateUpdate 晚于更新当Behaviour启用时,其LateUpdate在每一帧被调用。
LateUpdate是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。
Update和FixedUpdate的区别:
update跟当前平台的帧数有关,而FixedUpdate是真实时间,所以处理物理逻辑的时候要把代码放在FixedUpdate而不是Update.
Update是在每次渲染新的一帧的时候才会调用,也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体(可以认为是三角形的数量)。在性能好的机器上可能fps 30,差的可能小些。这会导致同一个游戏在不同的机器上效果不一致,有的快有的慢。因为Update的执行间隔不一样了。
而FixedUpdate,是在固定的时间间隔执行,不受游戏帧率的影响。有点想Tick。所以处理Rigidbody的时候最好用FixedUpdate。
PS:FixedUpdate的时间间隔可以在项目设置中更改,Edit->ProjectSetting->time 找到Fixedtimestep。就可以修改了。
Update和LateUpdate的区别
在圣典里LateUpdate被解释成一句话:LateUpdate是在所有Update函数调用后被调用。
LateUpdate是晚于所有Update执行的。例如:游戏中有2个脚步,脚步1含有Update和LateUpdate,脚步2含有Update,那么当游戏执行时,每一帧都是把2个脚步中的Update执行完后才执行LateUpdate 。虽然是在同一帧中执行的,但是Update会先执行,LateUpdate会晚执行。
现在假设有2个不同的脚本同时在Update中控制一个物体,那么当其中一个脚本改变物体方位、旋转或者其他参数时,另一个脚步也在改变这些东西,那么这个物体的方位、旋转就会出现一定的反复。如果还有个物体在Update中跟随这个物体移动、旋转的话,那跟随的物体就会出现抖动。 如果是在LateUpdate中跟随的话就会只跟随所有Update执行完后的最后位置、旋转,这样就防止了抖动。
做一个相机跟随主角的功能时,相机的位置调整写在LateUpdate()
对于人物的动画播放我们可以通过动画机,当然也可以直接用代码来实现动画播放,把动画拖动到player的animation中
在人物行走的代码如下:
public enum AnimState { run, idle } public class PlayerDir : MonoBehaviour { //鼠标左键单击的特效 public GameObject effect_click_prefab; //是否面向鼠标点击的位置 private bool isLookAt=false; //这个目标坐标是在另一个PlayerMove调用的坐标 public Vector3 TargetPos; private CharacterController cc; public float speed = 4; //设置人物的动画状态 public AnimState playerAnimationState = AnimState.idle; private void Start() { cc = GetComponent<CharacterController>(); //让角色一进游戏的目标位置为当前位置不发生移动 TargetPos = transform.position; } void Update () { if (Input.GetMouseButtonDown(0)) { Ray ray= Camera.main.ScreenPointToRay(Input.mousePosition); //用一个bool来看有没有射线碰撞,如果有,而且碰撞到地面的话就显示鼠标左键的特效 RaycastHit hitInfo; bool isCollider = Physics.Raycast(ray,out hitInfo); if(isCollider&&hitInfo.collider.tag==Tags.ground){ ShowClickEffect(hitInfo.point); isLookAt = true; } } else if (Input.GetMouseButtonUp(0)) { isLookAt = false; } if (isLookAt) { CharacterLookAtClick(); } else { Move(); } } //猪脚面向鼠标 void CharacterLookAtClick() { //这里有个非常值得注意的地方,为什么不直接把上面的hitInfo传过来拿到目标点而是还要在函数里再做射线, //因为GetMouseButtonDown只要按下只返回一次,如果按住鼠标需要通过Input.GetMouseButton来实时返回结果 //所以鼠标一直按住isLookAt还是true,那么在这个函数再做一次射线检测才行 RaycastHit hitInfo; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); bool isCollider = Physics.Raycast(ray, out hitInfo); if (isCollider && hitInfo.collider.tag == Tags.ground) { transform.LookAt(hitInfo.point); TargetPos = hitInfo.point; } } //如果鼠标点了一下,就实例化一个单击的特效 void ShowClickEffect(Vector3 hitPoint) { Instantiate(effect_click_prefab,hitPoint,Quaternion.identity); } //角色移动 void Move() { //这里注意的是如果我直接 if (Vector3.Distance(TargetPos,transform.position)>0.1)那么鼠标点击的y轴坐标和 //人物的y轴坐标是有距离的即使走到了该点距离仍然>0.1所以要让TargetPos的y取人物的y坐标 Vector3 v = new Vector3(TargetPos.x,transform.position.y,TargetPos.z); if (Vector3.Distance(v,transform.position)>0.1) {
transform.LookAt(v);//这句话必须得加上,因为如果不加意思是鼠标抬起,朝着目标点行走,按理说没有错,但是如果遇到高地或者石头让人物行走的角度
偏了一点那么会出现走到目标点仍然会行走的bug,所以要实时更新lookAt角度
cc.SimpleMove(speed*transform.forward); playerAnimationState = AnimState.run; } else { playerAnimationState = AnimState.idle; } } }动画的代码如下:
public class PlayerAnim : MonoBehaviour { private Animation anim; private PlayerDir dir; private void Start() { anim = GetComponent<Animation>(); //这里注意的是必须要拿到该脚本的组件,如果只是声明 private PlayerDir dir,直接调用dir.playerAnimationState //那么会报空指针 dir = GetComponent<PlayerDir>(); } private void LateUpdate() { //这里注意的是public enum AnimState要放到public class PlayerDir : MonoBehaviour的上面 //这样在这个脚本中调用上个脚本就直接拿到AnimState //还要注意在public enum AnimState命名的时候会突然报错,可能是AnimState会与插件的类名重合了 if (dir.playerAnimationState== AnimState.idle) { anim.CrossFade("Idle"); } else if(AnimState.run == dir.playerAnimationState) { anim.CrossFade("Run"); } } }下面添加相机跟随人物行走脚本
private Transform player; private Vector3 offsetPostion; void Start () { player = GameObject.FindGameObjectWithTag(Tags.player).transform; offsetPostion = transform.position - player.position; } //这里注意要让相机的位置等于人物Position+offsetPosition,那么相机的更新位置要放到LateUpdate中防止抖动 //如果放到update中,那么会感觉一卡一卡的 private void LateUpdate() { transform.position = player.position + offsetPostion; } void Update () { }
这个Name我们可以拿到它的名字
鼠标向前滑动input.GetAxis("Mouse ScrollWheel")为正值所以这样来在相机的脚本中这样做
//调整鼠标滚轮的视野拉近 void ScollView() { //视野的拉近改变的是相机镜头的距离角色的距离,而且这个距离是相机对角色的角度不变也即单位向量不变,改变长度 distance = offsetPostion.magnitude; distance -= scrollSpeed * Input.GetAxis("Mouse ScrollWheel"); // offsetPostion.magnitude = distance;如果这样不行,向量的长度是只读的不能赋值,要用它的单位向量乘以距离 offsetPostion = offsetPostion.normalized * distance; }
if (isRotate) { //mouse x是左右滑动鼠标右键,围绕猪脚这个点,垂直于猪脚的轴旋转 transform.RotateAround(player.position,player.up,rotateSpeed*Input.GetAxis("Mouse X")); //mouse x是上下滑动鼠标右键,围绕猪脚这个点,垂直于相机的左右轴旋转,这里非常容易出错,是相机的轴 transform.RotateAround(player.position, transform.right, -rotateSpeed * Input.GetAxis("Mouse Y")); }
标签:间隔 不同的 sha 点击 性能 lin 比较 first bool
原文地址:http://blog.csdn.net/zhangxiaofan666/article/details/70204961