My First RPG Game总结一

一进游戏把鼠标指针切换成想要的形状:

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);
    }
}

Update和LateUpdate和FixedUpdate的区别:

当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 () {
	}

对于鼠标滚轮的修改,Edit-->Project settings--->input

这个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"));
        }
时间: 2024-08-07 21:20:08

My First RPG Game总结一的相关文章

《游戏脚本的设计与开发》-(RPG部分)3.8 通过脚本来自由控制游戏(一)

注意:本系列教程为长篇连载无底洞,半路杀进来的朋友,如果看不懂的话,请从第一章开始看起,文章目录请点击下面链接. http://blog.csdn.net/lufy_legend/article/details/8888787 一,内容预览 算起来,游戏脚本系列文章已经很久没更新了,虽然该系列文章更新缓慢,但是确实还是能够帮到一些朋友,前段时间,仅仅因为做毕业设计通过邮件联系我的就有4位学生.有鉴于此,我还是挤点儿时间来继续慢慢更新一下了.另外,我想再声明一下,目前该脚本引擎还处在移植开发阶段,

开源一个C#写的Android和IOS都能跑的 打击感强的RPG玩玩。

不废话直接上图 关于下载和打开 没错,我强调过很多次的,Unity3D开发的.  如果你还不懂Unity3D 的基本开发套路,如何打开Unity如何安装Unity这些问题.我建议你先不要索要源代码. 下载后,直接打开这个工程......  然后打开根目录下载ManTuLanSi这个Scence  ,如果你是用PC,就可以按  ASDW开前  来控制前后左右.痛快的打一下怪吧. 源代码齐全吗?? 因为美术资源是别人的,所以实际源代码会有部分美术资源替换了.不过,代码还是这份代码.完全没变. 能商用

简易2D横版RPG游戏制作

Unity学习笔记1 简易2D横版RPG游戏制作 http://m.blog.csdn.net/article/details?id=24601905

基于cocos2dx的RPG简单实用算法之一 - 角色的移动

最近自己写RPG,发现在角色对象运动上面还是可以运动到不少的以前数学知识(经理各种纠结的脑补),好久没有写博客了,趁热总结一下算法思路,免得自己过两天又忘了. 已知角色速度和目的地,求每帧位置 已经知道了一个角色 bodyA 速度为 像素/秒 float speed  = 5 目的地为  Point  destination 当前地点为 Point currentPosition = bodyA.getPosition() 那么帧循环里面应该怎样计算角色的 当前位置呢? 方案1. 计算量小但是不

关于RPG的随想

听到很多人都在说关于RPG的一些理解.但是很多都提到了要有装备,背包,人物属性等等各种功能的列举.很少听到出发点的一个思考角度.可能网络游戏MMORPG而言,可能现在的快餐化对于世界观之类的已经非常的简约,可有可无只要有个套子就可以套进去就可以了,也不能说错的确玩家也不管那么多.那么不管是A-RPG,MMORPG等,没事儿自己想了一下,我是从下面几个角度进行分析的. 世界观: 不论是IP也好,还是自己写的幻想类世界观也好,起码得有一个模子来. 规则: 一个RPG,需要的是一种明了的,玩家可接受的

杭电---2068 RPG的错排

Problem Description  今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁.RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔:第二次猜:R是草儿,P是月野兔,G是公主:第三次猜:R是草儿,P是公主,G是月野兔:......可怜的野骆驼第六次终于把RPG分清楚了.由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只

国产单机RPG游戏的情怀

最近在玩儿仙剑奇侠传5,这个游戏从小时候玩儿到现在,也算是见证了一代人的成长,小时候没少玩盗版,现在自己工作了,有了固定的收入,也能体会到游戏开发者的不容易,尤其是单机游戏这个圈子,现在国内几乎没有人愿意做单机游戏,只有情怀,没有钱的事一般聪明的程序员们是不会做的,何况是一群俗不可耐的家伙. 话回到游戏中,这个游戏我玩儿到2/3的时候和韩总发表了一顿感慨,这游戏做的也太差了,游戏性差了之前太多,没什么可玩儿性,BOSS就是无限加血加蓝补怒耗着基本都能过.这番感慨发表的当天,剧情走到了一段叫“青木

HDU 4800 &amp; ZJU 3735 Josephina and RPG(状压dp)

题目链接: ZJU:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5081 HDU:http://acm.hdu.edu.cn/showproblem.php?pid=4800 Problem Description A role-playing game (RPG and sometimes roleplaying game) is a game in which players assume the roles of c

HDU 4800 Josephina and RPG

Josephina and RPG Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 605    Accepted Submission(s): 165Special Judge Problem Description A role-playing game (RPG and sometimes roleplaying game) is

Z - 不容易系列之(3)―― LELE的RPG难题

Description 人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深Cole终于知道了原因,原来,LELE最近研究起了著名的RPG难题:         有排成一行的n个方格,用红(Red).粉(Pink).绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法.         以上就是著名的RPG难题.         如果你是Co